6 Stimmen

C++ x86/x64 Strukturierung + .NET AnyCPU C++ Bibliothek Verwendung (Aufrufe/Rückrufe)

Da meine vorherige Frage keinen Erfolg hatte ("C# AnyCPU-Bibliothek unter Verwendung von x86/x64 C-API - Verpacken von Strukturen, Aufrufen und Rückrufen"), werde ich eine kürzere und abstraktere schreiben.

DER ZUSTAND:

Das Unternehmen, für das ich arbeite, hat eine Software, die auf 64 Bit portiert werden soll. Die Software besteht aus einer BASIS-Bibliothek (C++ mit C-API) und zwei Wrappern über das C-API: einem C++-Wrapper und einem .NET-Wrapper.

Die C++ BASIS-Bibliothek & C++ WRAPPER sollten x86/x64-Buildkonfigurationen haben. Der .NET-Wrapper sollte nur eine AnyCPU-Buildkonfiguration haben.

Das Auswählen der richtigen Bibliothek aus dem .NET-Wrapper wurde erfolgreich abgeschlossen (beide C++ BASIS-Bibliotheken (x86/x64) werden in zwei separaten Namensräumen geladen und abhängig von der Größe von IntPtr werden zur Laufzeit die richtigen Funktionen aufgerufen; dies erfordert nicht zwingend, dass beide Bibliotheken vorhanden sind, sondern nur diejenige, die verwendet wird).

DAS PROBLEM:

Alle Strukturen in der BASIS-Bibliothek sind auf 4 Byte ausgerichtet:

#pragma pack(push,4)

Um den Code ohne Warnungen in 64-Bit kompilieren zu lassen, habe ich selektive Ausrichtung hinzugefügt (C++ BASIS & C++ WRAPPER funktionieren wie ein Charme):

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

Das Problem betrifft die Strukturen in .NET:

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

Diese Struktur kann keine selektive Verpackung haben, da AnyCPU die einzige gewünschte WRAPPER-Konfiguration ist.

Es ist sehr schwierig (VIEL UND VIEL LEISTUNGSVERLUST), separate Strukturen auszurichten, die auf 8 Byte ausgerichtet sind, in einem anderen .NET-Namespace zu erstellen... Dennoch könnte dies die einzige Lösung sein, die vollständig funktioniert.

Die Rückkehr zur Ausrichtung auf 4 Bytes für x86 und x64 führt zu VIELEN Warnungen, da 100 % der Strukturen empfindlich auf die Verpackung reagieren, insbesondere bei den unären Operatoren (Probleme treten nur auf der x64-Lösungskonfiguration mit Ausrichtung auf 4 Byte auf). Viele Abstürze, die Strukturen können nicht ausgerichtet werden, es sei denn, wir fügen Dummy-Mitglieder hinzu. Ich sollte erwähnen, dass die Struktur basierend auf Bedeutung oder in Bezug auf Lizenz / Ziel-OS gruppiert sind (ifdefs). Das Hinzufügen von Polstern (Dummy)-Mitgliedern für alle Möglichkeiten würde Monate dauern.

Alles auf 8 Bytes auszurichten ist ebenfalls keine Lösung, da es wieder zu Abstürzen kommt - nur für x86 funktioniert es gut, für x64 erfordert die Strukturausrichtung wieder Dummy- (Polster-)Mitglieder und Gruppierung nach Größe.

DAS FAZIT (FRAGEN):

1) Ist es möglich, dass ein C++-Code für beide x86- und x64-Lösungskonfigurationen eine Ausrichtung von 4 hat? Wie kann dies erreicht werden?

2) Was ist die beste Alternative für x86- und x64-Ausrichtung? Die Größe des Zeigers sollte definitiv die Ausrichtung bestimmen (meiner Meinung nach). Wir streben eine SCHNELLE Software an, die nicht unbedingt speichereffizient sein muss (bislang beträgt der Speicher-Fingerprint irgendwo zwischen 15 MB und 2 GB auf x86-Systemen).

3) Welche besonderen Anforderungen haben Strukturen mit Funktionspointern hinsichtlich Interop zwischen .NET und C?

4) Jede vorgeschlagene Alternative ist sehr willkommen.

Wir suchen seit mehr als einem Monat im Internet (dem auf unserem Planeten), aber wir sind nicht weitergekommen. Einige Architekten plädieren für die Verwendung selektiven Packens (4/8), während einige argumentieren, dass die Software nicht einfach ist und überarbeitet werden sollte. Es ist nicht meine Entscheidung, was zu tun ist, aber ich kann Ideen mit guten Argumenten vorbringen. Die Software wurde Ende der 2000er Jahre gestartet, als die STL fehlerhaft war, sodass die BASIS ihre eigenen Container optimiert für Gott-weiß-was hat. Ich sollte hier keine Meinung äußern, da dies nicht christlich ist.

1voto

MSalters Punkte 166675

Beheben Sie einfach das Ausrichtungsproblem auf der C++-Seite. Es sollte keinen Grund geben, warum x86-Code bei einer 8-Byte-Ausrichtung abstürzt, noch warum x64 bei einer 4-Byte-Ausrichtung abstürzt. #pragma pack(push,4) wäre eine geeignete Methode. Möglicherweise benötigen Sie ein weiteres #pragma pack für internen SSE-Code, aber dieser Code sollte nicht für .Net AnyCPU-Code freigegeben werden.

Wenn Sie Hunderte von Warnungen erhalten (natürlich ohne Leistungs-Warnungen zu beachten), dann stimmt der Compiler meiner Einschätzung zu, dass Ihr Code verdächtig ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X