2010-10-29 15 views
59

Duplicar posible:
How to also prepare for 64-bits when migrating to Delphi 2010 and Unicode¿Cómo debo preparar mis programas Delphi de 32 bits para un eventual compilador de 64 bits?

Ya que creo que 64 bits Delphi compilador aparecerá pronto, Tengo curiosidad si alguien sabe qué tipo de programas que ahora son de 32 bits se compilará y funcionará sin ningún cambio cuando se usa 64bit comp iler.

y si hay una regla general, qué tipo de cambios que debe hacer sistemáticamente en nuestros viejos programas compilarse como 64 bits?

Es bueno estar preparado cuando el 64 bits compilador de repente estar aquí ...

Cualquier sugerencia será muy apreciada.

+8

Nominado para reapertura ya que esta pregunta parece producir respuestas infinitamente más útiles que el duplicado marcado. – Justin

+3

¿Qué te hace pensar que Embarcadero lanzará pronto un compilador Delphi de 64 bits? – Rowan

+0

Creo lo que prometen: http://edn.embarcadero.com/article/39934 ¿Alguien tiene información de que Delphi 64 no estará disponible en 2011? – Petra

Respuesta

0

Como una conjetura completa, cualquier código que no dependa de un tamaño de palabra específico, o que pueda adaptar su tamaño de palabra según lo que el compilador le indique, estará bien.

+0

¿Cómo llamas una "palabra"? En Delphi, una palabra es siempre un valor de 16 bits. Así que supongo que hablaste de "NativeInt" ... porque DWord siempre se quedará a 32 bit, como el entero también se quedará en 32 bit ... –

+0

Estoy usando la definición CE, no la definición Delphi. –

3

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 funciones de API que toman punteros como argumentos usen cardinal s en lugar del tipo de entero nativo (sin firmar).

Para hacer el código que funciona bien en cualquier plataforma, uno debe usar NativeUInt s (IIRC, no tiene un compilador Deplhi ahora) en lugar de cardinal s cuando se trabaja con punteros y enteros simultáneamente.

+1

Creo que es bastante común declarar API que toma punteros como parámetros de los indicadores :) También NativeUInt es un tipo relativamente nuevo, una vez que fue Cardinal el que desempeñó su rol. Hay algún problema, piense en la propiedad Etiqueta (nadie sabe aún en qué se convertirá), los tipos de wParam/lParam en los mensajes de Windows, los tamaños de los registros pueden cambiar. –

+2

@Indsandon: Es cierto, pero para muchas personas un puntero es simplemente un nombre elegante de un cardenal, y ese "error" ha funcionado bien desde hace bastante tiempo. Entonces es un problema posible. ¿Entonces la 'Etiqueta' podría convertirse en 64 bits? Supongo que no se romperá ningún código existente, aunque ... –

+1

http://twitter.com/#!/kylix_rd "Como se especula, la propiedad Tag se convertirá en NativeInt". –

4

Dependiendo de su código, puede intentar compilarlo usando FreePascal, que admite la compilación tanto de 32 bits como de 64 bits. El compilador le advertirá sobre posibles lugares erróneos en su código.

3

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).

Compruebe 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).

+1

TComponent.Tag debe ser NativeInt para manejar el caso esperado de las personas que lanzan referencias de TObject y similares dentro y fuera de él. Integer y Cardinal deben permanecer igual 32 bits, ya que esa es la política general en Windows de 64 bits; también debería reducir los cambios semánticos de cambio de bitness del objetivo. El ensamblador incorporado de 64 bits probablemente no existirá; con suerte, existirá un enlace de soporte para nasm o similar. –

+0

+1 principalmente por la mención de compatibilidad ASM, ya que he tenido esos problemas exactos desde el lanzamiento de Delphi XE2 (x64). –

8

En primer lugar, 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 relacionado 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 sean 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 aumentará 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 compilador 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.

+7

En Windows de 64 bits, el modelo es para int y largo para permanecer de 32 bits. En consecuencia, Delphi seguirá con Integer y Longint permanecerá en 32 bits. Además, en Delphi, las enumeraciones siempre han tenido el tipo más pequeño capaz de representar su rango. –

+0

De Delphi 1 a Delphi 2, el tipo entero cambió de 2 bytes a 4. Dado que es el tipo de entero genérico, espero que aumente nuevamente, aunque Embarcadero podría mantenerlo en 4 bytes. Las enumeraciones utilizarán el tamaño más pequeño que se ajuste a todos los valores, pero puede especificar un tamaño mínimo para los tipos de enumeración usando {$ Z1} o {$ Z2} o {$ Z4} {$ MINENUMSIZE 1} o {$ MINENUMSIZE 2} o {$ MINENUMSIZE 4}. Creo que también podrían agregarle {$ Z8}. Esto está relacionado con los registros (empaquetados) y su alineación de los campos de registro. –

+10

@Workshop Alex - Estoy en el equipo de compiladores Emabarcadero Delphi; confía en mí cuando digo que Integer se mantendrá de 32 bits :) –

2

Además de la obvia puntero < -> int tareas: (usando IntPtr/nativeint/PtrInt etc)

  • Cualquier cosa que usted tiene como un blob binario (DLL quizá OCX, etc) deben ser actualizados. Esto puede 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 ensamblador y otros trucos muy bajo nivel (por ejemplo, depende de la disposición de VMT, el formato de depuración (seguimientos) loading talones dinámicos como en Jedi Apilib etc.) necesita ser actualizado
  • cheque todas propias cabeceras creadas por los cambios en el embalaje y malas traducciones eso importa ahora el puntero <> entero. El bit de empaque no debe ser subestimada
  • Interfaz con Office y otras aplicaciones externas podrían cambiar
  • TComponent.tag es un entero largo ahora, y por lo tanto podría permanecer entero largo, lo que significa que los esquemas de esas cosas punteros en component.tag pueden fallar.
  • x87 La FPU está obsoleta 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 de embalaje de registros es algo que noté cuando transfiero encabezados existentes a win64.

+0

A menos que ocurra alguna incompatibilidad inesperada, TComponente .Tag debe convertirse casi seguro en NativeInt. –

+0

FPC lo dejó longint –

+0

Curioso: ¿alguna métrica sobre (a) cuántas aplicaciones creadas con FPC confiaban en Tag para hacer referencia a un objeto, y (b) rompieron con un objetivo de 64 bits? –

80

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.

que decía:

  • Hay dos tipos de enteros, NativeInt y NativeUInt, cuyo tamaño se de inmersión entre 32 bits y 64 bits dependiendo de la plataforma. Han estado en durante algunos lanzamientos. Ningún otro tipo entero cambiará el tamaño dependiendo de la bitidez del objetivo.

  • asegurarse de que cualquier lugar que se basa en emitir un valor de puntero a un número entero o viceversa está utilizando NativeInt o NativeUInt para el número entero tipo. TComponent.Tag debe ser NativeInt en versiones posteriores de Delphi.

  • Sugeriría 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.

  • cosas Pointer-como debe atenerse a unas normas similares a los punteros: objeto referencias (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 de cambios en la API de 64 bits debe ser mantener la misma API entre 32 bits y de 64 bits siempre que sea posible, incluso si esto significa que la API de 64 bits no necesariamente toma ventaja de la máquina. Para el ejemplo , TList probablemente solo maneje elementos MaxInt div SizeOf (Pointer) , para mantener Count, indexes, etc. como Integer. Debido a que el tipo entero no flotará (es decir, cambiará el tamaño dependiendo del bitness), no deseamos tener efectos dominantes en el código del cliente: cualquier índice que alteró a través de una variable de tipo entero o for-loop index, se truncaría y podría causar errores sutiles.

  • Cuando API están extendidos para 64 bits, lo más probable es hacerse con una función/método/propiedad adicional para acceder a los datos adicionales, y esto API también estará apoyado en 32 bits. Por ejemplo, la rutina estándar de Length() probablemente devolverá valores de tipo Integer para argumentos de tipo string o dynamic array; si uno quiere tratar con matrices dinámicas muy grandes , también puede haber una rutina LongLength(), cuya implementación de en 32 bits es igual a 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.

  • relación a esto, es probable que haya mejorado comprobación de errores para operaciones de estrechamiento de la lengua, especialmente la reducción de 64 bits valora ubicaciones a 32 bits. Esto afectaría la usabilidad de asignar el valor de retorno de Longitud a las ubicaciones de tipo Entero si Length(), devolviera Int64. Por otro lado, específicamente para compilar-magic funciones como Length(), puede haber alguna ventaja de la magia tomada, a, p. Ej. cambiar el tipo de devolución en función del contexto. Pero la ventaja no puede ser tomada de manera similar en API no mágicas.

  • Las matrices dinámicas probablemente admitirán la indexación de 64 bits. Tenga en cuenta que las matrices 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. Tenemos un tiempo difícil que viene con razones realistas para las personas que desean 4GB + cadenas que realmente son cadenas, y no solo bloques de datos administrados, para los cuales las matrices dinámicas pueden funcionar igual de bien.

  • Quizás 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 pila que deben seguirse en x64.

+17

Ouch, que ningún bit de ensamblador me lastimará mucho. Tengo un montón de código SSE en mis aplicaciones de visión. Sí, lo sé, probablemente tendré que alterarlos mediante push/popping regs en x86_64, pero una actualización que encontrar una solución diferente. –

+0

"Length() arrojaría una excepción en 64 bits si se aplica a una matriz dinámica con más de 232 elementos." Umm ... 232? –

+6

@Marco: +1. Sin ASM realmente lastimará a mucha gente. –

1

Mis 2 centavos:

  • en los viejos tiempos cada escritor ASM a empujados a USAR BASM

  • asm64 externa sería aceptable y el uso de la vieja xy.obj inlclude código, mientras que se requiere una reescritura completa

  • Debugger & CPU64: la pregunta será esto todavía está allí?

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

Hp

4

Muchas preguntas similares cuando se les pidió que se anunció que Delphi 2009 no haría sino crear aplicaciones Unicode. Al final resultó que la mayoría del código existente funcionaba perfectamente sin cambios. Las partes difíciles eran código que suponía que SizeOf(Char) = 1 y componentes de terceros que podrían estar haciendo eso.

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

Debe utilizar SizeOf(Pointer) en lugar de SizeOf(NativeInt) si desea que su código funcione con Delphi 2007. Delphi 2007 tiene un error desafortunado que causa SizeOf(NativeInt) para volver 8 en lugar de 4 como debería. Esto fue arreglado en Delphi 2009.

+0

Hice mi transformación a Unicode bastante rápido, pero de todos modos hubo – Petra

+0

bastantes cambios: todas las IORoutines (restablecer, leer, reescribir, escribir) para leer y escribir en archivos ya no funcionan para Unicode, en cada procedimiento escribir cadenas apropiadas La fuente Unicode debe ser posible de seleccionar.Pero en general, la transición se realizó sin problemas. – Petra

Cuestiones relacionadas