2012-09-13 16 views
7

Esiste un modo per applicare condizionatamente un attributo a una struttura?Attributo struct differente basato su 32 bit o 64 bit

Se la macchina è 32bit voglio applicare questo attributo

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

Se la macchina è 64bit voglio applicare questo attributo

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

Oppure, in alternativa potrei sostituire un valore all'interno dell'attributo ...

32bit (confezione = 2)

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

64bit (confezione = 8)

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

Ho provato ad utilizzare questo example ma è per gli attributi personalizzati, non esistente quelli.

Aggiornamento:

  • mi piacerebbe comile a "Qualsiasi CPU"
  • L'attributo è per il SHFILEOPSTRUCT ea seconda del processore usa o.
  • Non voglio dover compilare due versioni.
+1

Compilerai il programma staticamente a 64 e 32 bit, o stai usando "Any CPU" e vuoi comportarti diversamente in fase di runtime? –

+0

Se solo la classe 'StructLayoutAttribute' non è stata sigillata. Doh! – simonlchilds

+1

potresti riuscire a farlo con direttive di compilazione condizionale. –

risposta

6

Buona domanda.

La risposta che ho pensato prima era direttive del preprocessore e assiemi compilati a 32 e 64 bit. È possibile utilizzare lo stesso codice, anche lo stesso progetto, basta creare e distribuire in due modi a seconda del sistema di destinazione:

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

Ciò richiederebbe la definizione Bit32 e Bit64 costanti di compilazione per il progetto sulla base della architettura target, e probabilmente costruendo la tua app due volte.

Se si desidera eseguire questa operazione in fase di esecuzione, non penso sia possibile a meno che non si emetta l'intera classe dinamicamente in fase di esecuzione. Gli attributi possono avere solo dati costanti e non possono essere applicati in modo condizionale in fase di esecuzione (le direttive del preprocessore operano in fase di compilazione, non in fase di esecuzione).

L'unico altro modo che posso pensare di fare ciò è copiare la definizione della classe in due spazi dei nomi e utilizzare in modo condizionale l'uno o l'altro in base alla proprietà Environment.Is64BitOperatingSystem. È possibile utilizzare questa proprietà per controllare in modo condizionato la classe istanziata o la strategia per la creazione scelta (quale metodo di produzione o modello correlato viene utilizzato), ma non è possibile controllare in modo condizionale gli attributi in fase di runtime; le loro informazioni vengono compilate staticamente nel manifesto dell'assembly come metadati. Questo in particolare viene utilizzato dal runtime stesso per definire come memorizza i membri dell'oggetto come dati heap e non si cerca mai realmente questo attributo nel codice utente e lo si usa per definire il comportamento (ignorando o specificando un pacchetto condizionale valore in fase di esecuzione).

+0

+1. Emetti al runtime suona come un approccio divertente. –

+0

È divertente allo stesso modo essere legati e soffocati in camera da letto è divertente; sicuramente ha una certa mentalità per guardarlo in quel modo. – KeithS

+0

sì, dovrei scegliere le mie parole più attente - divertente come in "eccitante, interessante, avventuroso ma improbabile redditizio". Penso che "legato e strozzato" sia un paragone troppo cupo, a meno che non si decida su un tale approccio per un codice di produzione reale. –

0

Non penso che tu possa farlo. Basta avere 2 strutture e fornire un modo per convertire entrambe in struct o class condivise per la gestione ...

Nota: la funzione richiesta è molto strana (diverso layout esplicito della struttura basato sul tipo di JIT che è accaduto in fase di esecuzione). Nella maggior parte dei casi questo è utilizzato per il layout fisico dei byte che corrisponde a un protocollo fisso ben noto indipendentemente dalla bittness dell'applicazione. Potresti considerare il tuo caso come dotato di 2 protocolli/interope diversi per i casi x86/x64 e sii felice con 2 strutture.

1

Creare due diversi target di compilazione (uno per 32 bit, uno per 64 bit), aggiungere un simbolo di compilazione condizionale per ciascuno (x86 per uno, x86_64 per l'altro) e utilizzare #ifdef attorno alle definizioni della struttura.

+0

Nessun aumento: (.... Penso che questo approccio funzionerebbe - compilare 2 versioni della stessa classe/struct e caricarne dinamicamente una in fase di esecuzione a seconda del processo corrente "bitness. In questo modo si ha una struct/class e può facilmente usarlo nel resto del codice senza strani ifdefs –

+0

@Alexei Levenkov - dovrei dire, non voglio davvero compilare due versioni. – Rob

Problemi correlati