developer tip

최종 64 비트 컴파일러를 위해 32 비트 Delphi 프로그램을 어떻게 준비해야합니까?

copycodes 2020. 12. 8. 08:24
반응형

최종 64 비트 컴파일러를 위해 32 비트 Delphi 프로그램을 어떻게 준비해야합니까?


이 질문에 이미 답변이 있습니다.

중복 가능성 :
Delphi 2010 및 유니 코드로 마이그레이션 할 때 64 비트를 준비하는 방법

내가 있다고 생각하기 때문에 64 비트 델파이 컴파일러가 곧 나타날 것입니다, 나는 누군가가 알고 있다면 궁금 종류 지금하는 프로그램의 어떤 32 비트를 사용하는 경우 변경없이 컴파일 및 작동 64 비트 컴파일러.

그리고 일반적인 규칙이 있다면 64 비트로 컴파일하기 위해 이전 프로그램에서 체계적으로 어떤 변경을해야 합니까?

64 비트 컴파일러가 갑자기 여기에 올 때 대비하는 것이 좋습니다 .

어떤 제안이라도 대단히 감사하겠습니다.


먼저 면책 조항 : 비록 내가 Embarcadero에서 일하지만. 고용주를 대변 할 수 없습니다. 내가 작성하려는 내용은 가상의 64 비트 델파이가 어떻게 작동해야하는지에 대한 내 의견을 기반으로하지만, 다른 설계 결정을 내릴 수있는 다른 예측 또는 예상치 못한 비 호환성 및 이벤트가있을 수도 있고 없을 수도 있습니다.

즉,

  • 플랫폼에 따라 크기가 32 비트와 64 비트 사이에서 부동하는 두 가지 정수 유형, NativeInt 및 NativeUInt가 있습니다. 그들은 꽤 많은 릴리스를 위해 주변에있었습니다. 다른 정수 유형은 대상의 비트에 따라 크기가 변경되지 않습니다.

  • 포인터 값을 정수로 또는 그 반대로 캐스팅하는 데 의존하는 모든 위치가 정수 유형에 NativeInt 또는 NativeUInt를 사용하고 있는지 확인하십시오. TComponent.Tag는 이후 버전의 Delphi에서 NativeInt 여야합니다.

  • 포인터 기반이 아닌 값에는 NativeInt 또는 NativeUInt를 사용하지 않는 것이 좋습니다 . 32 비트와 64 비트 사이에서 코드를 의미 상 동일하게 유지하십시오. 32 비트 범위가 필요하면 Integer를 사용하십시오. 64 비트가 필요한 경우 Int64를 사용하십시오. 이렇게하면 코드가 두 비트 모두에서 동일하게 실행됩니다. 참조 또는 THandle과 같은 어떤 종류의 포인터 값으로 /에서 캐스팅하는 경우에만 NativeInt를 사용해야합니다.

  • 또는 PByte우선적으로 포인터 산술에 사용 합니다 . 대부분의 목적에 충분하며 일반 정수 유형으로 (쉽게) 착각 할 수없고 그 반대의 경우도 가능하기 때문에 더 유형 안전합니다.NativeIntNativeUInt

  • 포인터와 같은 것들은 포인터와 비슷한 규칙을 따라야합니다 : 객체 참조 (분명히), HWND, THandle 등과 같은 것들도 마찬가지입니다.

  • 헤더 데이터와 같은 문자열 및 동적 배열의 내부 세부 정보에 의존하지 마십시오.

  • 64 비트 API 변경에 대한 Google의 일반적인 정책은 64 비트 API가 반드시 시스템을 활용하지 않는다는 것을 의미하더라도 가능한 경우 32 비트와 64 비트간에 동일한 API를 유지하는 것입니다. 예를 들어 TList는 Count, indexes 등을 Integer로 유지하기 위해 MaxInt div SizeOf (Pointer) 요소 만 처리합니다. Integer 유형은 부동하지 않기 때문에 (즉, 비트에 따라 크기가 변경됨) 고객 코드에 파급 효과가 생기는 것을 원하지 않습니다. Integer 유형 변수 또는 for 루프 인덱스를 통해 라운드 트립 된 인덱스는 잘려서 잠재적으로 미묘한 버그를 일으킬 수 있습니다.

  • API가 64 비트 용으로 확장 된 경우 추가 데이터에 액세스하기 위해 추가 기능 / 메서드 / 속성으로 수행 될 가능성이 높으며이 API는 32 비트에서도 지원됩니다. 예를 들어, Length () 표준 루틴은 문자열 또는 동적 배열 유형의 인수에 대해 Integer 유형의 값을 반환 할 것입니다. 매우 큰 동적 배열을 처리하려는 경우 LongLength () 루틴도있을 수 있습니다.이 루틴의 32 비트 구현은 Length ()와 동일합니다. Length ()는 요소가 2 ^ 32 개를 초과하는 동적 배열에 적용될 경우 64 비트에서 예외를 throw합니다.

  • 이와 관련하여 언어의 축소 작업, 특히 64 비트 값을 32 비트 위치로 축소하기위한 오류 검사가 개선 될 것입니다. 이것은 Length ()가 Int64를 반환하는 경우 Length의 반환 값을 Integer 유형의 위치에 할당하는 유용성을 떨어 뜨릴 것입니다. 다른 한편으로, 특히 Length ()와 같은 컴파일러-매직 함수의 경우, 예를 들어 컨텍스트에 따라 리턴 유형을 전환하는 것과 같은 일부 장점이있을 수 있습니다. 그러나 비 마법 API에서는 이와 유사하게 이점을 얻을 수 없습니다.

  • 동적 배열은 아마도 64 비트 인덱싱을 지원할 것입니다. Java 배열은 64 비트 플랫폼에서도 32 비트 인덱싱으로 제한됩니다.

  • 문자열은 아마도 32 비트 인덱싱으로 제한 될 것입니다. 우리는 사람들이 실제로 문자열 인 4GB 이상의 문자열을 원하는 실제적인 이유를 찾는 데 어려움을 겪습니다.

  • 아마도 내장 된 어셈블러 일 수도 있지만, 델파이 코드와 자유롭게 혼합 할 수없는 것과 같은 제한이 있습니다. x64에서 따라야하는 예외 및 스택 프레임 레이아웃에 대한 규칙도 있습니다.


우선, FreePascal은 이미 64 비트 지원을 제공합니다. 하지만 델파이가 아닙니다.
둘째, 델파이 1이 델파이 2로 업그레이드되었을 때 있었던 것과 동일한 문제가있을 것으로 예상합니다. 가장 큰 문제는 대부분 주소 공간과 관련이 있으며 여기서 문제는 포인터가 4 바이트에서 8 바이트로 확장된다는 것입니다. WIN16에서는 2 바이트를 사용하고 포인터에 세그먼트와 오프셋을 사용하여 64KB 경계를 넘기려면 트릭이 필요했습니다. (여러 작업에 기본 세그먼트를 사용할 수 있습니다.)
또한 특정 데이터 유형이 지금보다 커질 가능성도 있습니다. 정수 유형은 대부분 8 바이트입니다. (Windows 2에서는 2 바이트에 불과했습니다.) 열거 형도 더 커질 것입니다. 그러나 대부분의 다른 데이터 유형은 현재 크기를 유지할 가능성이 있으므로 여기에서 너무 많이 변경하지 마십시오.
또 다른 문제는 메모리 요구 사항입니다. 포인터의 길이는 8 바이트이므로 많은 포인터를 사용하는 응용 프로그램도 더 많은 메모리를 차지합니다. 포인터가 10.000 개인 목록은 40.000 바이트에서 80.000 바이트로 증가합니다. 32 비트 시스템보다 약간 더 많은 메모리를 사용할 수 있습니다.
속도도 약간 바뀝니다. 프로세서는 이제 8 바이트를 동시에 처리하므로 데이터를 훨씬 빠르게 처리 할 수 ​​있습니다. 그러나 포인터와 일부 데이터 유형이 커지기 때문에이를 일부 장치 또는 메모리로 수신하거나 보내는 속도가 약간 느려집니다. 일반적으로 응용 프로그램은 일반적으로 약간 더 빠르지 만 일부 부분은 실제로 느려질 수 있습니다!
마지막으로 Windows API를 변경하려면 64 비트 API 함수를 사용해야합니다. Delphi 컴파일러는 코드가 32 비트 API 함수를 호출 할 수 있도록 스마트 한 작업을 수행 할 수 있지만 프로세서가 이제 네이티브 64 비트 모드와 에뮬레이트 된 32 비트 모드 사이를 전환하기 때문에 성능이 저하 될 수 있습니다.


코드에 따라 32 비트 및 64 비트 컴파일을 모두 지원하는 FreePascal을 사용하여 컴파일을 시도 할 수 있습니다. 컴파일러는 코드에서 오류가있을 수있는 위치에 대해 경고합니다.


Delphi 2009가 유니 코드 응용 프로그램 만 만들 것이라고 발표했을 때 유사한 질문이 많이 나왔습니다. 결국 대부분의 기존 코드가 변경없이 잘 실행된다는 것이 밝혀졌습니다. 까다로운 부분은이를 가정 한 코드 SizeOf(Char) = 1와이를 수행 할 수있는 타사 구성 요소였습니다.

I would expect the move to 64-bit Delphi to be a similar experience. Everything just works out of be box, except for code that plays tricks with pointers and assumes that SizeOf(Pointer) = 4 or SizeOf(Pointer) = SizeOf(Integer). You can already fix such issues today by calling SizeOf(Pointer) rather than hardcoding 4 and using NativeInt or NativeUInt when you need pointer-sized integers.

You should use SizeOf(Pointer) rather than SizeOf(NativeInt) if you want your code to work with Delphi 2007. Delphi 2007 has an unfortunate bug that causes SizeOf(NativeInt) to return 8 instead of 4 as it should. This was fixed in Delphi 2009.


The vast majority of simple applications should work just fine. As far as I can see, only applications that manually make use of pointers are at a risk. Indeed, if a pointer now is 64-bit, and you use it in calculations together with integers or cardinals (that are still 32-bit by default), you will get into trouble. I also think it is rather common that declarations for API functions that take pointers as arguments are using cardinals instead of the (unsigned) native integer type.

To make code that works well on any platform, one should use NativeUInts (IIRC, don't have a Deplhi compiler right now) instead of cardinals when working with pointers and integers simultaneously.


As long as Embarcadero doesn't release official informations about their 64 bit implementation is not easy to tell. You should check any cast to/from Pointer, Integer and Cardinal assuming they are the native platform size, including object properties and references (i.e. storing an Integer in a TObject property, which is a pointer, or using Tag to store references and not numbers).

You must also ensure no code relies on the "wrap-around" effect when incrementing (or decrementing) a value at its maximum (minimum) size.

Check any code in structures that relies on the data size, and don't use SizeOf() correctly, and at large that SizeOf() is always used when the datasize matters. Check code that writes/read data to files, if sizes can change, especially if data need to be exchanged between 32 and 64 bit code.

Check Win64 changes, if the application calls API and manages Windows messages directly. Handcoded ASM code must be checked for 64 bit compatibility (there are far stricter rule to write 64 bit assembler).


Besides the obvious pointer<-> int tasks: (using intptr/nativeint/ptrint etc)

  • Anything that you have as a binary blob (DLLs maybe OCX etc) need to be upgraded. This might include old SDKs for dongles etc.
  • All tools that do something on binary level (debuggers,profilers, phone home tools) might need updates.
  • Nearly all assembler and other very lowlevel tricks (e.g. dependant on VMT layout, debug format (tracebacks) dynamic loading stubs like in Jedi Apilib etc) needs to be updated
  • check all own created headers for changes in packing and mistranslations that matter now pointer<>integer. The packing bit must not be underestimated
  • Interfacing with Office and other external apps might change
  • TComponent.tag is a longint now, and thus might remain longint, meaning that schemes that stuff pointers into component.tag may fail.
  • x87 FPU is deprecated on x64, and in general SSE2 will be used for florating point. so floating point and its exception handling might work slightly differently, and extended might not be 80-bit (but 64-bit or, less likely 128-bit). This also relates to the usual rounding (copro controlwork) changes when interfacing wiht C code that expects a different fpu word.

The packing of records problem is something I noticed when porting existing headers to win64.


My 2 cents:

  • in the old days every asm writer was to pushed to USE BASM

  • external asm64 would be acceptable and the using the old inlclude xy.obj code, while any way a complete rewrite is required

  • Debugger & CPU64: the question will be is this still there??

  • D64 Float Extended: Is this still maintained as 80 bit float??

Hp


As a complete guess, any code that doesn't depend on a specific word size, or can adapt its word size based on what the compiler tells it, will be fine.

참고URL : https://stackoverflow.com/questions/4051603/how-should-i-prepare-my-32-bit-delphi-programs-for-an-eventual-64-bit-compiler

반응형