2013-04-23 11 views
6

Come la mia domanda precedente non ha avuto successo ("C# Libreria AnyCPU che utilizza API C x86/x64 - strutture di imballaggio, chiamate e callback") , Scriverò uno più conciso e astratto.Allineamento struttura C++ x86/x64 + .NET AnyCPU Uso libreria C++ (chiamate/callback)

NELLA FOTO:

L'azienda dove lavoro ha un software per il porting a 64 bit. Il software consiste in una libreria BASE (C++ con API C) e due wrapper oltre l'API C: un wrapper C++ e un wrapper .NET.

La libreria C++ BASE & C++ WRAPPER deve avere configurazioni di generazione x86/x64. .NET WRAPPER deve avere solo una configurazione di compilazione AnyCPU.

Il prelievo della libreria corretta da .NET WRAPPER è stato completato correttamente (entrambe le librerie C++ BASE (x86/x64) vengono caricate in due spazi dei nomi separati e in base alla dimensione di IntPtr vengono richiamate le funzioni corrette in fase di esecuzione; non richiede necessariamente che entrambe le librerie siano lì, ma solo quella da utilizzare).

IL PROBLEMA:

Tutte le strutture presenti nella libreria BASE sono allineati su 4 byte:

#pragma pack(push,4) 

Al fine di avere il codice compilato senza avvisi a 64 bit, ho aggiunto allineamento selettivo (C++ BASE & C++ lavoro contenitore quale ciondoli):

#ifdef WIN64 
#pragma pack(push,8) 
#else 
#pragma pack(push,4) 
#endif 

Il problema è connesse alle strutture NET:

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] 
    internal struct DBConnectionSettings{...} 

Questa struttura non può avere imballaggio selettiva poiché AnyCPU è l'unica configurazione WRAPPER desideri.

È molto difficile (MOLTE E MOLTE PERDITE DI PERFORMANCE) creare strutture separate allineate su 8 byte in un diverso spazio dei nomi .NET ... Tuttavia, questa potrebbe essere l'unica soluzione che potremmo trovare pienamente funzionante.

ricadere per allineamento 4-byte per questioni sia x86 e x64 SACCO di allerta come 100% delle strutture sono sensibili al confezionamento, soprattutto per gli operatori unari (problemi appaiono solo dalla configurazione soluzione x64 con allineamento su 4 byte). Un sacco di arresti anomali, le strutture non possono essere allineate a meno che non aggiungiamo membri fittizi. Devo dire che la struttura è raggruppata in base al significato o al sistema operativo di licenza/obiettivo (ifdefs). Aggiungere membri padding (fittizi) a tutte le possibilità richiederebbe mesi.

Allineamento tutto su 8 byte non è una soluzione né poiché otteniamo crash allover il posto ancora una volta - solo per x86, x64 funziona bello - allineamento della struttura richiede di nuovo fittizio (imbottitura) membri e il raggruppamento in base alle dimensioni.

conclusione (domande):

1) E 'possibile che un codice C++ avere allineamento di 4 per entrambe le configurazioni x86 e x64 soluzione? Come può essere realizzato?

2) Qual è la migliore alternativa per l'allineamento x86 e x64? La dimensione del puntatore dovrebbe sicuramente governare l'allineamento (secondo me). Stiamo cercando di avere software FAST, non necessariamente efficiente in termini di memoria (finora l'impronta digitale della memoria è da qualche parte tra 15mb e 2gb su sistemi x86).

3) Quali esigenze speciali hanno le strutture che hanno funzione di puntatori rispetto all'interop tra .NET e C?

4) Qualsiasi alternativa suggerita è molto apprezzata.

Abbiamo cercato per più di un mese su questo Internet (quello sul nostro pianeta) ma non siamo arrivati ​​da nessuna parte. Alcuni architetti dichiarano di utilizzare l'imballaggio selettivo (4/8) mentre alcuni sostengono che il software non è diretto e che dovrebbe essere refactored. Non è una mia decisione cosa fare, ma posso portare idee con buoni argomenti. Il software è stato avviato alla fine del 2000, quando l'STL era bacato, quindi la BASE ha i suoi contenitori ottimizzati per Dio sa cosa. Non dovrei esprimere la mia opinione qui poiché non è cristiano.

risposta

1

Basta correggere il problema di allineamento sul lato C++. Non ci dovrebbero essere motivi per il blocco del codice x86 sull'allineamento a 8 byte, né per l'arresto di x64 sull'allineamento a 4 byte. #pragma pack(push,4) sarebbe un metodo adatto. Potrebbe essere necessario un altro #pragma pack per il codice SSE interno, ma tale codice non deve essere esposto al codice AnyNetU .Net.

Se ricevi centinaia di avvisi (ignorando ovviamente gli avvisi perfetti), il compilatore concorda con la mia valutazione che il tuo codice è sospetto.

+0

Hi MSalters, Senza alcun input, è stato deciso che il riallineamento verrà eseguito, indipendentemente dalle strutture dipendenti dalla licenza e dalle strutture dipendenti dal sistema. Ancora, lascerò questo argomento aperto per qualsiasi altra soluzione che possa essere pubblicata. È solo che ora sono curioso di sapere cosa si può fare con un tale codice ..... PS: non è il mio codice;) – ro0ter