Ich habe eine C-Bibliothek. Es hat viele Funktionsaufrufe wie folgt:
%Vor%Die Bibliothek selbst wird zur Laufzeit dynamisch geladen (eher wie ein Plugin). Die Header sind über alle Plattformen hinweg konsistent.
Mein Problem ist, dass unter Windows und 32bit Linux, unsigned long 32bits ist, aber auf 64bit linux sind das 64bits.
Die verschiedenen Implementierungen dieser Bibliothek akzeptieren das. Sie müssen Ihr C-Programm (wie erwartet) für die richtige Zielplattform erstellen.
Abhängig von der Architektur muss meine Interop-Methode eine davon sein.
%Vor%Die C # -Typen, die ich verwenden kann, sind feste Größe auf allen Plattformen (wie sie sein sollten). Daher wird mein verwaltetes long , das von .Net / Mono übergeben wurde, immer ein nicht verwaltetes uint64_t sein.
Wie kann ich mit dieser variablen Integer-Größe umgehen, habe aber eine einzelne Assembly, die im 32bit- oder 64bit-Modus auf .Net oder Mono läuft?
Das Problem ist, dass auf 64bit Windows C long immer noch 32bit ist, anders als auf Linux, wo es 64bit ist und das ein bisschen schmerzt.
Wenn Sie nicht beabsichtigen, 64-Bit-Windows zu unterstützen, ist es einfach - Sie können das Long in Ihrer DllImport-Definition IntPtr zuordnen. IntPtr ist 32bit sowohl auf 32-Bit-Windows als auch auf Linux, was gleich lang ist. Lange auf 64bit Linux ist auch 64bit und so ist IntPtr, aber auf Windows 64bit, während IntPtr 64bit lang ist 32bit.
Wenn Sie 64bit Windows unterstützen wollen, können Sie vielleicht zwei Signaturen gleichzeitig definieren - eine für 64bit und eine für 32bit wie folgt:
%Vor%Dann können Sie in Ihrem Code zur Laufzeit dynamisch entscheiden, welchen man so nennen soll:
%Vor% P.S: Wenn Sie nicht auf .NET 4 sind, können Sie mit bool is64Bit = IntPtr.Size == 8