2012-09-13 7 views
7

¿Hay alguna manera de que pueda aplicar un atributo a una estructura de forma condicional?Diferente atributo de estructura basado en 32 bits o 64 bits

Si la máquina es 32 bits quiero aplicar este atributo

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

Si la máquina es 64 bits quiero aplicar este atributo

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

O, alternativamente, podría sustituir un valor dentro del atributo ...

32 bits (Paquete = 2)

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

64 bits (Paquete = 8)

[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]

He intentado utilizar esta example pero es para los atributos personalizados, no existiendo unos.

Actualización:

  • me gustaría comilla a "Cualquier CPU"
  • El atributo es para el SHFILEOPSTRUCT y dependiendo del procesador utiliza o.
  • No quiero tener que compilar dos versiones.
+1

¿Va a compilar el programa estáticamente 64 y 32 bit, o está usando "Any CPU" y quiere comportarse de manera diferente en el tiempo de ejecución? –

+0

Si solo la clase 'StructLayoutAttribute' no está sellada. Doh! – simonlchilds

+1

, puede hacer esto con las directivas de compilación condicional. –

Respuesta

6

Buena pregunta.

La respuesta que primero pensé fueron directivas de preprocesador y ensamblajes compilados de 32 y 64 bits. Se puede utilizar el mismo código, incluso el mismo proyecto, simplemente construir e implementar de dos maneras, dependiendo del sistema de destino:

#ifdef Bit32 
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)] 
#endif 
#ifdef Bit64 
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)] 
#endif 

Para ello sería necesario definir Bit32 y Bit64 constantes de compilación para su proyecto basado en la arquitectura objetivo, y probablemente construyas tu aplicación dos veces.

Si desea hacer esto en tiempo de ejecución, no creo que sea posible a menos que emita la clase completa dinámicamente en tiempo de ejecución. Los atributos solo pueden tener datos constantes y no se pueden aplicar condicionalmente en el tiempo de ejecución (las directivas del preprocesador operan en tiempo de compilación, no en tiempo de ejecución).

La única otra manera en que puedo pensar para hacer esto es copiar la definición de clase en dos espacios de nombres y usar condicionalmente uno u otro en función de la propiedad Environment.Is64BitOperatingSystem. Puede usar esta propiedad para controlar condicionalmente qué clase crea una instancia, o qué estrategia de creación elige (qué método de fábrica o patrón relacionado se utiliza), pero no puede controlar los atributos en tiempo de ejecución; su información está compilada estáticamente en el manifiesto del ensamblaje como metadatos. Este en particular es utilizado por el tiempo de ejecución para definir cómo almacena los miembros del objeto como datos del montón, y nunca busca realmente este atributo en el código del usuario y lo usa para definir el comportamiento (ignorando o especificando un paquete condicional) valor en tiempo de ejecución).

+0

+1. Emitir en tiempo de ejecución suena como un acercamiento divertido. –

+0

Es divertido de la misma manera que estar atado y ahogado en el dormitorio es divertido; definitivamente toma una cierta mentalidad para verlo de esa manera. – KeithS

+0

Sí, debería elegir mis palabras con más cuidado, divertidas como "emocionantes, interesantes, aventureras pero poco rentables". Creo que "atado y ahogado" es una comparación demasiado lúgubre, a menos que haya una razón por la que uno decida tal enfoque para el código de producción real. –

0

No creo que pueda hacer eso. Simplemente tenga 2 estructuras y proporcione una forma de convertirlas en una estructura o clase compartida para su manejo ...

Nota: la función que está solicitando es muy extraña (diferente diseño explícito de la estructura basado en el tipo de JIT que sucedió en el tiempo de ejecución) En la mayoría de los casos, esto se usa para el diseño físico de bytes que coincide con algún protocolo fijo conocido independiente de la bittness de la aplicación. Puedes considerar que tu caso tiene 2 protocolos/interoperaciones diferentes para casos x86/x64 y estar contento con 2 estructuras.

1

Cree dos objetivos de compilación diferentes (uno para 32 bit, uno para 64 bit), agregue un símbolo de compilación condicional para cada uno (x86 para uno, x86_64 para el otro) y use #ifdef alrededor de las definiciones de estructura.

+0

No más votaciones ascendentes: (... Creo que este enfoque funcionaría: compile 2 versiones de la misma clase/estructura y cargue dinámicamente una en tiempo de ejecución según el bitness del proceso actual. De esta forma, tiene una estructura/clase y puede usarlo fácilmente en el resto del código sin ifdefs extraño –

+0

@Alexei Levenkov - debería decirse, realmente no quiero compilar dos versiones. – Rob

Cuestiones relacionadas