2009-10-14 4 views
13

다음 버전에서는 64 비트 지원이 필요하지 않으므로 기존 코드 기반을 유니 코드로 마이그레이션 할 가능성을 기다리는 옵션은 더 이상 필요하지 않습니다. 한 번에 비트. 그러나 유니 코드 변환을 수행 할 때 64 비트 용 코드를 이미 준비 할 수 있으면 좋을 것입니다. 그러면 버전 2020에 최종적으로 나타날 이벤트에 미치는 영향을 최소화 할 수 있습니다. 2020 년까지 도착하지 않으면 많은 혼란을 야기하지 않고 이러한 문제에 어떻게 대처할 수 있을까요?Delphi 2010 및 유니 코드로 마이그레이션 할 때 64 비트를 준비하는 방법

+1

다음과 같은 질문이 일부 도움이 될 수 있습니다 http://stackoverflow.com/questions/4051603/how-should-i-prepare-my-32-bit-delphi-programs-for-an- 궁극적 인 64 비트 컴파일러 – Justin

답변

7

먼저 델파이가 아닌 라이브러리 및 API 호출과 상호 작용하는 장소 인 이 다를 수 있습니다. Win32에서 stdcall 호출 구문을 가진 라이브러리의 이름은 _SomeFunction @ 4 (@ 4는 매개 변수의 크기를 나타내는 등)입니다. Win64에서는 하나의 호출 규칙 만 있고 dll의 함수는 더 이상 장식되어 있지 않습니다. dll 파일에서 함수를 가져 오는 경우이를 조정해야 할 수도 있습니다.

64 비트 exe에서는 32 비트 dll을로드 할 수 없으므로 타사 dll 파일을 사용하는 경우 해당 파일의 64 비트 버전도 확인해야합니다.

또한 최대 값에 의존하는 경우 Integers를 살펴보십시오. 예를 들어 오버플로하게하고 순간 발생을 기다리는 경우 정수 크기가 변경되면 문제가 발생합니다.

또한 스트림을 사용할 때 정수가 포함 된 다른 데이터를 직렬화하려는 경우 정수의 크기가 변경되어 스트림이 동기화되지 않아 문제가 발생할 수 있습니다.

따라서 정수 또는 포인터의 크기에 의존하는 위치에서 조정해야합니다. Sush 데이터를 직렬화 할 때 32 비트와 64 비트 버전간에 데이터 비 호환성이 발생할 수 있으므로이 크기 문제를 염두에 두어야합니다.

또한, Lazarus IDE가있는 FreePascal 컴파일러는 이미 64 비트를 지원합니다. 이 대안의 오브젝트 파스칼 컴파일러는 Borland/Codegear/Embarcadero Pascal의 100 % 호환이 아니므로 64 비트 용으로 다시 컴파일하는 것만으로는 간단하지 않을 수도 있지만 64 비트의 문제점을 지적하는 데 도움이 될 수 있습니다.

6

64 비트로의 변환이 그리 고통스럽지 않아야합니다. 중요한 곳에서 정수의 크기에 대해 의도적으로 시작하십시오. "정수"를 사용하지 마십시오. 대신 32 비트의 정수에는 Int32를 사용하고 64 비트의 정수에는 Int64를 사용하십시오. 마지막 비트 변환에서 Integer의 정의는 Int16에서 Int32로 변경되었으므로 정확한 비트 심도를 지정하여 안전하게 재생할 수 있습니다.

인라인 어셈블리가 있으면 파스칼을 생성하고 동일한 방법으로 작동하는지 확인하기 위해 몇 가지 단위 테스트를 작성하십시오. 두 가지 타이밍 테스트를 수행하고 조립품이 계속해서 더 빨리 작동하는지 확인하십시오. 그렇다면 필요한 경우 두 가지 모두를 변경해야합니다.

+3

정수 크기에 의존하는 특별한 경우 중 하나는 정수 및 포인터가 * 같은 * 크기가 될 수있는 크기 여야합니다. 또한 정수 및 * 핸들 *이 같은 크기라고 가정합니다. 델파이는 오늘날 핸들을 정수로 취급하지만 API는 포인터를 포인터로 정의합니다. –

2

캐스팅 된 포인터를 포함 할 수있는 정수에는 NativeInt를 사용하십시오.

+1

명확히하기 : 포인터 (예 : 32 또는 64 비트)와 크기가 같아야하는 부호있는 유형과 부호없는 유형은 각각 NativeInt 및 NativeUInt로 선언 할 수 있습니다. – PhiS

20

another similar question는하지만 많은 사람들이이 정보를 참조로 확실하게, 너무 여기 내 대답을 반복합니다 :

첫번째로, 면책 조항 : 나는 엠바 카데로 작동하지만. 나는 고용주를 대변 할 수 없다. 필자가 작성하려고하는 것은 가상의 64 비트 델파이가 어떻게 작동해야하는지에 대한 내 자신의 견해에 기반하고 있지만 대안적인 설계 결정을 내리는 예상치 못한 예측 불가능한 비 호환성 및 이벤트가있을 수도 있고 그렇지 않을 수도 있습니다.상기

:

  • 크기가 32 비트 및 64 비트 사이 플로트 플랫폼에 따라 두 가지 종류의 정수, 및 nativeint로 NativeUInt가있다. 꽤 많은 방출을 위해 주위에 이었습니다. 다른 정수 유형은 대상의 비트 수에 따라 크기 을 변경하지 않습니다.

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

  • 포인터가 아닌 값에 NativeInt 또는 NativeUInt를 사용하지 마십시오. 코드를 의미 적으로 32 비트와 64 비트간에 동일하게 유지하십시오. 32 비트 범위가 필요하면 정수를 사용하십시오. 64 비트가 필요하면 Int64를 사용하십시오. 그렇게하면 코드가 두 bitnesses에서 동일하게 실행됩니다. 참조 또는 THandle과 같은 일종의 Pointer 값으로 캐스팅하는 경우에만 NativeInt를 사용해야합니다.

  • 포인터 같은 포인터와 비슷한 규칙을 따라야 일 : 객체 (명백하게) 참조뿐만 아니라 등 HWND, THandle, 같은 것들

  • 문자열과 동적 배열의 내부 세부 사항에 의존하지 마십시오 예 : 의 헤더 데이터 64 비트 API 변경에

  • 우리의 일반적인 정책은 64 비트 API가 반드시 활용하지 않는 것을 의미한다하더라도, 32 비트 및 64 비트 수 사이의 동일한 API를 유지해야한다 의 기계. 예를 들어, 의 경우 TList는 Count, indexes 등을 Integer로 유지하기 위해 MaxInt div SizeOf (Pointer) 요소 만 처리합니다. 정수 유형이 부동화되지 않으므로 (비트 크기에 따라 크기가 변경됨) 은 고객 코드에 파급 효과를 미치지 않으려합니다. 이 정수 유형 변수를 통해 라운드 트립 된 모든 색인 또는 for 루프 인덱스 은 잘 리거나 미묘한 버그가 발생할 수 있습니다. API를 64 비트 연장된다

  • , 그들은 가장 가능성이 여분의 데이터에 액세스 할 수 와 추가 기능/메소드/속성을 할 것이며,이 API는 또한 32 비트에서 지원됩니다. 예를 들어, Length() 표준 루틴은 유형 문자열 또는 동적 배열 인수에 대해 Integer 유형의 값을 리턴합니다. 매우 큰 동적 배열을 처리하려면 LongLength() 루틴이있을 수 있습니다.이 루틴의 길이는 32 비트의 구현이 Length()와 같습니다. 길이가 255보다 큰 동적 배열에 적용되는 경우 은 64 비트 예외로 throw됩니다. 요소

  • 이와 관련하여 특히 언어의 좁게 작업에 대한 오류 검사가 개선 될 예정이며, 특히 32 비트 위치에 대해 의 64 비트 값을 좁히는 것이 좋습니다. length(), 이 Int64를 반환하면 Integer 유형의 위치에 Length의 반환 값을 할당하는 것이 유용합니다.반면에, 컴파일러 - 마술을 위해 특별히 은 Length()와 같은 기능을 수행하며, 마법의 효과가있을 수 있습니다. 컨텍스트에 따라 반환 유형을 전환하십시오. 그러나 장점은 비 마법 API에서 마찬가지로 취해진 일 수 없습니다.

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

  • 문자열은 32 비트 색인 생성으로 제한됩니다. 우리는 실제로 시간이 흐르고 있습니다. 동적 배열이 제대로 작동 할 수있는 데이터의 관리되는 방울이 아니라 실제로 문자열 인 4GB + 문자열 을 원하는 사람들에게 현실적인 이유가 있습니다.

  • 아마도 빌트인 어셈블러이지만 제한적으로, 델파이 코드와 자유롭게 섞일 수없는 것 같습니다. x64에서 따라야 할 예외 및 스택 프레임 레이아웃에 관한 규칙도 있습니다.