¿Cómo debo preparar mis progtwigs Delphi de 32 bits para un eventual comstackdor de 64 bits?

Posible duplicado:
Cómo prepararse para 64 bits al migrar a Delphi 2010 y Unicode

Dado que creo que el comstackdor Delphi de 64 bits aparecerá pronto, tengo curiosidad si alguien sabe qué tipo de progtwigs que ahora son de 32 bits comstackrán y trabajarán sin ningún cambio cuando usen el comstackdor de 64 bits .

Y si existe una regla general, ¿qué tipo de cambios deberíamos hacer sistemáticamente en nuestros viejos progtwigs para comstackrlos como 64 bits ?

Es bueno estar preparado cuando el comstackdor de 64 bits esté aquí de repente …

Cualquier sugerencia será muy apreciada.

Primero, un descargo de responsabilidad: aunque trabajo para Embarcadero. No puedo hablar por mi empleador. Lo que voy a escribir se basa en mi propia opinión de cómo debería funcionar un hipotético Delphi de 64 bits, pero pueden existir o no opiniones contrapuestas y otras incompatibilidades y eventos previstos o imprevistos que causan decisiones de diseño alternativas.

Eso dijo:

  • Hay dos tipos enteros, NativeInt y NativeUInt, cuyo tamaño flotará entre 32 bits y 64 bits según la plataforma. Han estado presentes durante bastantes lanzamientos. Ningún otro tipo entero cambiará de tamaño dependiendo de la bitidez del objective.

  • Asegúrese de que cualquier lugar que dependa de convertir un valor de puntero a un número entero o viceversa está usando NativeInt o NativeUInt para el tipo de entero. TComponent.Tag debe ser NativeInt en versiones posteriores de Delphi.

  • Sugeriría que no use NativeInt o NativeUInt para valores que no sean punteros . Trate de mantener su código semánticamente igual entre 32 bits y 64 bits. Si necesita 32 bits de rango, use Integer; si necesita 64 bits, use Int64. De esta forma, su código debería correr igual en ambas bitnesses. Solo si está transfiriendo desde y hacia un valor de puntero de algún tipo, como una referencia o un THandle, debe usar NativeInt.

  • Utilice PByte para la aritmética del puntero siempre que sea posible, con preferencia a NativeInt o NativeUInt . Será suficiente para la mayoría de los propósitos, y es más seguro debido a que no se puede (fácilmente) confundir con un tipo entero normal, y viceversa.

  • Las cosas parecidas a punteros deberían seguir reglas similares a los punteros: referencias de objeto (obviamente), pero también cosas como HWND, THandle, etc.

  • No confíe en los detalles internos de cadenas y matrices dinámicas, como sus datos de encabezado.

  • Nuestra política general sobre los cambios de API para 64 bits debería ser mantener la misma API entre 32 bits y 64 bits siempre que sea posible, incluso si eso significa que la API de 64 bits no aprovecha necesariamente la máquina. Por ejemplo, TList probablemente solo maneje elementos MaxInt div SizeOf (Pointer), para mantener Count, indexes, etc. como Integer. Debido a que el tipo Integer no flotará (es decir, cambiará el tamaño dependiendo del bitness), no queremos tener efectos dominantes en el código del cliente: cualquier índice que dispare en redondo a través de una variable de tipo entero o for-loop index, estar truncado y potencialmente causar errores sutiles.

  • Cuando las API se extiendan para 64 bits, lo más probable es que se realicen con una función / método / propiedad adicional para acceder a los datos adicionales, y esta API también se admitirá en 32 bits. Por ejemplo, la rutina estándar Length () probablemente devolverá valores de tipo Integer para argumentos de tipo string o dynamic array; si uno quiere tratar arreglos dynamics muy grandes, también puede haber una rutina LongLength (), cuya implementación en 32 bits es lo mismo que Length (). Length () arrojaría una excepción en 64 bits si se aplica a una matriz dinámica con más de 2 ^ 32 elementos.

  • En relación con esto, probablemente habrá una mejor verificación de errores para las operaciones de estrechamiento en el lenguaje, especialmente el estrechamiento de los valores de 64 bits a las ubicaciones de 32 bits. Esto afectaría a la facilidad de uso de asignar el valor de retorno de Longitud a ubicaciones de tipo Entero si Longitud (), devuelto Int64. Por otro lado, específicamente para las funciones mágicas del comstackdor como Length (), puede haber alguna ventaja de la magia tomada, por ejemplo, cambiar el tipo de devolución en función del contexto. Pero la ventaja no se puede tomar de manera similar en las API que no son mágicas.

  • Las matrices dinámicas probablemente admitirán la indexación de 64 bits. Tenga en cuenta que las matrices de Java están limitadas a la indexación de 32 bits, incluso en plataformas de 64 bits.

  • Las cadenas probablemente estarán limitadas a la indexación de 32 bits. Nos cuesta mucho encontrar razones realistas para personas que desean cadenas de 4GB + que realmente sean cadenas, y no solo bloques de datos administrados, para los cuales las matrices dinámicas también pueden servir.

  • Tal vez un ensamblador incorporado, pero con restricciones, como no poder mezclar libremente con el código Delphi; también hay reglas sobre excepciones y diseño de marco de stack que deben seguirse en x64.

Antes que nada, FreePascal ya ofrece soporte para 64 bits. Aunque no es Delphi.
En segundo lugar, espero los mismos problemas que existían en el momento en que Delphi 1 se actualizó a Delphi 2. El mayor problema es principalmente el espacio de direcciones y el problema aquí es que los punteros se ampliarán de 4 bytes a 8 bytes. En WIN16 solían ser de 2 bytes y se necesitaba un truco para superar el límite de 64 KB mediante el uso de segmentos y desplazamientos para los punteros. (Con la posibilidad de usar segmentos predeterminados para varias tareas).
También es probable que ciertos tipos de datos se vuelvan más grandes de lo que son ahora. El tipo entero será de 8 bytes, lo más probable. (Solía ​​tener solo 2 bytes en Windows 2.) Las enumeraciones probablemente también serán más grandes. Pero es probable que la mayoría de los demás tipos de datos mantengan su tamaño actual, por lo que no hay demasiados cambios aquí.
Otro problema serán los requisitos de memoria. Como los punteros tendrán una longitud de 8 bytes, una aplicación que usa muchos de ellos también consumirá mucha más memoria. Una lista con 10.000 punteros boostá de 40,000 bytes a 80,000 bytes. Es posible que desee utilizar un poco más de memoria que en un sistema de 32 bits.
La velocidad también cambiará un poco. Como el procesador ahora maneja 8 bytes al mismo tiempo, puede procesar datos mucho más rápido. Pero como los punteros y algunos tipos de datos se hacen más grandes, recibirlos o enviarlos a algún dispositivo o memoria será un poco más lento. En general, sus aplicaciones serán un poco más rápidas en general, pero algunas partes podrían volverse más lentas.
Finalmente, los cambios en la API de Windows requerirán que use las funciones de la API de 64 bits. Tal vez el comstackdor Delphi hará algo inteligente para permitir que el código llame a las funciones API de 32 bits, pero esto ralentizaría el rendimiento porque ahora el procesador cambia entre el modo nativo de 64 bits y el modo emulado de 32 bits.

Dependiendo de su código, puede intentar comstackrlo usando FreePascal, que admite la comstackción de 32 bits y de 64 bits. El comstackdor le advertirá sobre posibles lugares erróneos en su código.

Se hicieron muchas preguntas similares cuando se anunció que Delphi 2009 solo crearía aplicaciones Unicode. Al final resultó que la mayoría del código existente funcionaba perfectamente sin cambios. Las partes SizeOf(Char) = 1 fueron código que suponía que SizeOf(Char) = 1 y componentes de terceros que podrían estar haciendo eso.

Esperaría que la transición a Delphi de 64 bits sea una experiencia similar. Todo sale de be box, excepto por el código que juega trucos con punteros y asume que SizeOf(Pointer) = 4 o SizeOf(Pointer) = SizeOf(Integer) . Ya puede solucionar estos problemas llamando a SizeOf(Pointer) lugar de hardcoding 4 y usando NativeInt o NativeUInt cuando necesite enteros de tamaño puntero.

Debería usar SizeOf(Pointer) lugar de SizeOf(NativeInt) si desea que su código funcione con Delphi 2007. Delphi 2007 tiene un desafortunado error que hace que SizeOf(NativeInt) devuelva 8 en lugar de 4 como debería. Esto fue arreglado en Delphi 2009.

La gran mayoría de las aplicaciones simples deberían funcionar bien. Por lo que puedo ver, solo las aplicaciones que usan punteros de forma manual están en riesgo. De hecho, si un puntero ahora es de 64 bits y lo usa en cálculos junto con enteros o cardenales (que todavía son de 32 bits por defecto), se meterá en problemas. También creo que es bastante común que las declaraciones para las funciones de API que toman punteros como argumentos estén usando cardinal lugar del tipo de entero nativo (sin firmar).

Para crear un código que funcione bien en cualquier plataforma, uno debe usar NativeUInt s (IIRC, no tiene un comstackdor Deplhi en este momento) en lugar de cardinal s cuando se trabaja con punteros y enteros simultáneamente.

Mientras Embarcadero no publique información oficial sobre su implementación de 64 bits no es fácil de decir. Debe verificar cualquier conversión a / desde Puntero, Entero y Cardenal suponiendo que son el tamaño de la plataforma nativa, incluidas las propiedades y referencias del objeto (es decir, almacenar un Entero en una propiedad TObject, que es un puntero, o usar Etiqueta para almacenar referencias y no números )

También debe asegurarse de que ningún código se base en el efecto “envolvente” al incrementar (o disminuir) un valor en su tamaño máximo (mínimo).

Verifique cualquier código en estructuras que dependa del tamaño de los datos, y no use SizeOf () correctamente, y en general que SizeOf () siempre se use cuando importa el tamaño de la información. Compruebe el código que escribe / lee datos en los archivos, si los tamaños pueden cambiar, especialmente si los datos deben intercambiarse entre códigos de 32 y 64 bits.

Compruebe los cambios de Win64, si la aplicación llama a API y gestiona los mensajes de Windows directamente. El código ASM codificado a mano debe verificarse para la compatibilidad de 64 bits (hay una regla mucho más estricta para escribir el ensamblador de 64 bits).

Además de las tareas obvias del puntero < -> int: (usando intptr / nativeint / ptrint, etc.)

  • Cualquier cosa que tengas como un blob binario (DLL tal vez OCX, etc.) debe actualizarse. Esto podría incluir SDK antiguos para dongles, etc.
  • Es posible que todas las herramientas que hacen algo en el nivel binario (depuradores, perfiladores, herramientas de inicio del teléfono) necesiten actualizaciones.
  • Casi todos los ensambladores y otros trucos de bajo nivel (por ejemplo, dependientes del diseño de VMT, del formato de depuración (tracebacks), talones de carga dynamics como Jedi Apilib, etc.) deben actualizarse.
  • compruebe todos los encabezados creados para ver los cambios en el embalaje y las traducciones incorrectas que importan ahora puntero <> entero. El bit de embalaje no debe subestimarse
  • La interfaz con Office y otras aplicaciones externas pueden cambiar
  • TComponent.tag ahora es un longint, y por lo tanto puede permanecer longint, lo que significa que los esquemas que incluyen punteros en component.tag pueden fallar.
  • La FPU x87 está en desuso en x64 y, en general, SSE2 se utilizará para el punto flotante. por lo tanto, el punto flotante y su manejo de excepciones podrían funcionar de forma ligeramente diferente, y extendido podría no ser de 80 bits (pero de 64 bits o, menos probable, de 128 bits). Esto también se relaciona con los cambios habituales de redondeo (control de coproducción) al interconectarse con el código C que espera una palabra fpu diferente.

El problema del embalaje de registros es algo que noté cuando transfiero encabezados existentes a win64.

Mis 2 centavos:

  • en los viejos tiempos cada escritor de ASM era empujado a usar BASM

  • Asm64 externo sería aceptable y el uso del antiguo incluye el código xy.obj, mientras que de cualquier forma se requiere una reescritura completa

  • Depurador y CPU64: la pregunta será: ¿sigue ahí?

  • D64 Float Extended: ¿Esto se mantiene como flotador de 80 bit?

Hp

Como una conjetura completa, cualquier código que no dependa de un tamaño de palabra específico, o puede adaptar su tamaño de palabra en función de lo que el comstackdor le dice, estará bien.