2009-02-13 10 views
27

La mayor parte de mi programación reciente ha sido en Windows de 32 bits utilizando C/C++/C#/VB6. Últimamente, mis clientes me preguntan si mi código se ejecutará en Windows de 64 bits.Como programador, ¿de qué debo preocuparme cuando me muevo a Windows de 64 bits?

Me pregunto qué características heredadas podría utilizar que se rompen en Windows de 64 bits? ¿Cuáles son algunos de los problemas del mundo real en los que debo pensar y preocuparme?

Obviamente, voy a probar mi código en el sistema operativo de 64 bits, pero me gustaría saber qué problemas comunes buscar. Me preocupan más los binarios existentes, pero estoy abierto a comentarios sobre qué preocuparme cuando vuelva a compilar (cuando sea posible).

EDITAR: Aquí está un nice list de errores de portabilidad de 64 bits.

+0

¿Qué idioma? Esto hace una gran diferencia :) –

+0

Tengo muchos códigos Win32 en varios idiomas: C, C++ y VB6. También tengo el código .NET en C# - No estoy seguro de si eso podría tener el mismo tipo de problemas. –

+1

Aprende * Por qué * hay un problema que va de 32 bits a 64 bits. –

Respuesta

5

Puede ser más fácil migrar el código .NET si tiene 100% "escriba el código administrado de forma segura". Puede copiarlo a la plataforma de 64 bits y ejecutarlo correctamente con el CLR de 64 bits. Compruebe esto MSDN link al migrar el código administrado de 32 bits a 64 bits.

Btw, hanselman blogged sobre el tema recientemente.

+0

Ese es un buen consejo para el código .NET. –

3

Si hablamos de programas de 32 bits, no tiene prácticamente nada de qué preocuparse, ya que Windows 64 los ejecutará bajo emulación como de 32 bits. Cualquier problema con futuras versiones de Windows (por ejemplo, Windows 7) es probable que sean incompatibilidades en lugar de problemas con un sistema operativo de 64 bits.

Sin embargo, si su código administrado se compila para la plataforma de destino "Cualquier CPU" y realiza llamadas en código no administrado (por ejemplo, PInvoke) o depende de otros ensamblajes, hay algunos aspectos a tener en cuenta. El post de Scott Hanselman sobre el CLR x86/x64 cubre esto y es una buena explicación del CLR en Win32/64.

Al desarrollar programas nativos de 64 bits, el Programming Guide for 64-bit Windows es una buena guía. Se trata en gran parte a los punteros y el tamaño de los tipos de datos :)

0

Desde un/C perspectiva C++ ....

Una cosa obvia es que el tamaño de un int se convertirá en 8 bytes en lugar de 4 bytes . Si alguno de sus códigos depende de eso, puede obtener resultados inesperados. La estructura y las alineaciones variables pueden cambiar. Es posible que pueda superarlo con un paquete #pragma, pero no soy muy fluido en las alineaciones y el embalaje.

Si usa cualquier unión con entradas, el comportamiento puede cambiar.

Si está utilizando cualquier estructura de campo de bits, en función de los datos, los 32 bits adicionales pueden causar confusión. El bit de signo no estará donde pensaste que estaba.

Si codifica las constantes hexadecimales y espera que los signos se vuelvan negativos, es posible que tenga problemas. Ejemplo 0x8000000 es un número negativo como un registro o entero de 32 bits. 0x80000000 como un número entero en una plataforma de 64 bits es un número positivo. para establecer directamente el bit de signo que debería usar 0x80000000 00000000 (espacio incrustado para legibilidad solamente)

También espero que size__t crezca adecuadamente. Si está haciendo asignaciones basadas en MAX_INT, serán mucho más grandes.

Para evitar este tipo de anomalías de tamaño, generalmente me quedo con largos en lugar de enteros.

+0

Bueno, debería usar algo como http://en.wikipedia.org/wiki/Stdint.h para realmente especificar los bits que desea. – Calyth

+0

¿Todavía no tiene 32 bits en Win64? – Peter

+0

int sigue siendo de 32 bits en Win64 - no tan obvio, supongo :) –

2

Los programas de 32 bits se ejecutarán correctamente en las ventanas de 64 bits. Siempre que no esté haciendo ningún tipo de desarrollo de controlador de dispositivo, por supuesto.

Si compila su software como un software de 64 bits la primera vez, tendrá que hacerse cargo de lo siguiente:

  • un puntero es de 64 bits de ancho, mientras que un int es de 32 bits. No guardes punteros en ints, tu código se romperá.
  • proceso de 64 bits necesita DLL de 64 bits. Si depende de archivos DLL de terceros, asegúrese de que también se proporcionen en 64 bits. Si necesita comunicarse entre un proceso de 32 bits y un proceso de 64 bits, necesitará algunas de las muchas formas diferentes de IPC en Windows. Llamar a las funciones directamente está fuera de toda duda.
  • Los directorios del sistema en Windows de 64 bits son diferentes que en Windows de 32 bits. Si tiene algunas rutas codificadas, es posible que deba verificarlas nuevamente.
+0

Según lo observado por otros, hay muchas más cosas que se podrían hacer suponiendo un determinado tamaño entero que se rompería. No creo que sea correcto ignorarlo y decir que mientras no hagas ningún controlador de dispositivo, estarás bien. – Calyth

+0

Todavía tengo que ver una aplicación de 32 bits en las ventanas de 64 bits, siempre que no sea un controlador de dispositivo. Simplemente no se ejecutan en Windows de 64 bits. – nusi

+0

Lanzar un puntero a un int se ha utilizado en tantos proyectos y posiblemente malas muestras que es LA fuente común de problemas de 32-> 64 bits. Aún no he visto ningún tipo de otro uso legal de los constructos de los lenguajes que el OP solicitó y que vale la pena mencionar. – nusi

0

¿La emulación de 32 bits es realmente a prueba de balas? He visto que el registro se presenta un poco diferente. Solo me pregunto qué cosas típicas no funcionan ...

Además, el directorio C: \ windows \ SYSTEM32 solo puede contener DLL de 64 bits. Si tiene un archivo DLL de 32 bits, debe colocarlo en C: \ windows \ syswow64 \

20

Por lo que a mí respecta, lo más importante acerca de portar el código C/C++ a Windows de 64 bits es probar la aplicación con MEM_TOP_DOWN asignaciones habilitados (AllocationPreference valor de registro) como se describe en 4-Gigabyte Tuning:

para forzar las asignaciones de asignar direcciones más altas antes de las direcciones más bajas para los propósitos de prueba, especifique MEM_TOP_DOWN al llamar VirtualAlloc o establecer el siguiente valor de registro a 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

¿Cuándo es esto importante?

  • Si ha EXE de 32 bits que fueron construidos con la opción del vinculador /LARGEADDRESSAWARE MSVC (o que tienen la bandera IMAGE_FILE_LARGE_ADDRESS_AWARE encuentra en sus encabezados PE a través de otros medios, tales como editbin.exe) existente, entonces consiguen un total de 4 GB de espacio de direcciones virtuales en Windows de 64 bits, y debe probarlos con el valor de registro AllocationPreference establecido.
  • Si tiene archivos DLL de 32 bits existentes que pueden cargarse mediante EXEs de direcciones grandes, debe probarlos con el valor de registro AllocationPreference establecido.
  • Si vuelve a compilar su código C/C++ en un archivo EXE o DLL de 64 bits, debe probarlo con el valor de registro AllocationPreference establecido.

Si su C/C++ aplicación cae en una de estas tres categorías y no se prueba con MEM_TOP_DOWN asignaciones, la prueba es muy poco probable que atrapar cualquier error de truncamiento puntero/de signo en el código.

La segunda cosa más importante, si se utiliza MSVC y que está volviendo a compilar el código C/C++ para 64 bits, es utilice la opción /Wp64 compilador para su 64 bits acumulación:

  • Esto causará que el compilador emita advertencias para los tipos de letra que truncan los punteros o extienden tipos integrales más pequeños en los punteros (incluso cuando se usa reinterpret_cast o un molde de estilo C), así como algunos otros problemas de puertos de 64 bits.
  • Sí, el documentation dice que en lugar de compilar con /Wp64 debe usar un compilador dirigido a una plataforma de 64 bits, pero que solo no detectará los problemas de truncamiento/extensión del puntero en tiempo de compilación. El uso de un compilador dirigido a y de 64 bits que habilita la opción de compilación /Wp64 para la compilación de 64 bits detectará muchos problemas de truncamiento/extensión de puntero en tiempo de compilación, y esto le ahorrará tiempo a largo plazo.
  • Desafortunadamente, con MSVC 2008, esto también producirá una "advertencia de línea de comando" para cada unidad de traducción diciendo que la opción /Wp64 está en desuso. Puedo ver por qué la opción está en desuso para las compilaciones de 32 bits (donde es un hack malvado que requiere anotar muchos de sus typedefs), pero es desafortunado que también esté en desuso para las compilaciones de 64 bits (donde en realidad es útil).
+0

Acepto que forzar las asignaciones a estar por encima de la línea de 4 GB es realmente importante, pero usar 'MEM_TOP_DOWN' puede hacer que las asignaciones sean realmente lentas si haces muchas de ellas. Otra forma de forzar asignaciones para que tengan direcciones "altas" es reservar todas las direcciones "bajas". Aquí hay una técnica que he usado: http://stackoverflow.com/a/29220631/1339280 – shoelzer

1

Si lo hace la inyección de DLL, por cualquier motivo que tendrá problemas.

Cuestiones relacionadas