P / Invoke und .NET Target Framework [Duplikat]

Jan 22 2021

Dieses Problem treibt mich an die Wand ... Nur zu sagen.

Mein Unternehmen verfügt über eine ältere C ++ - Bibliothek und ich wurde beauftragt, einen .NET-Wrapper zu erstellen.
Ich habe keine Erfahrung mit C ++ oder P / Invoke, daher versuche ich zunächst eine einfache Methode.

Ich habe die offizielle Dokumentation gelesen und auch ein schönes Tutorial gefunden .
Ich habe jedoch festgestellt, dass das .NET-Zielframework der konsumierenden App einen Unterschied macht.
Der P / Invoke-Code aus dem Lernprogramm funktioniert einwandfrei, aber ich habe festgestellt, dass er auf das .NET Framework 4-Clientprofil abzielt .
Wenn ich Haltepunkte platziere, werden sie getroffen und alles funktioniert wie erwartet. Wenn ich ein Framework höher als 4 anvisiere, stürzt das Programm ausnahmslos ab.

Ich habe eine wirklich einfache Methode in C ++ definiert:
framework.h

extern "C" {
    API char* SayHello();
}

dllmain.cpp

char* SayHello() {
    return (char*)"Hello";
}

C#

        [DllImport("PInvokeTest.dll")]
        public static extern string SayHello();

(Ich habe versucht, CallingConvention und CharSet für das Attribut in verschiedenen Kombinationen festzulegen. Ich habe es geschafft, chinesische Zeichen zu erhalten, aber nichts funktioniert höher als Framework 4.)

In meinem C ++ - Projekt sind API=__declspec(dllexport)Präprozessordefinitionen festgelegt und _stdcall (\Gz)die Aufrufkonvention ist (ich habe auch _cdecl ausprobiert).
Das C # -Projekt funktioniert in Framework 4 einwandfrei . Wenn ich etwas darüber hinaus ändere, wird es ausnahmslos beendet.
Ich habe auch eine Abhängigkeits-GUI gefunden , die mir zeigt, dass sie SayHellotatsächlich vorhanden ist.

Unsere Firma verwendet 4.6.1. Ich bin auch auf diesen Artikel gestoßen , der mich zu PInvokeStackImbalance führte, aber das macht in meinem Fall nichts.

Jede Hilfe wäre sehr dankbar.
Ich könnte bei Bedarf ein temporäres GitHub-Repo erstellen.

Antworten

LukeTO'Brien Jan 22 2021 at 19:50

Jetzt, da ich weiß, dass es sich um ein String-Problem handelt, habe ich ein wenig gesucht und diese SO-Frage gefunden .
Am Ende habe ich den BSTRAnsatz verwendet.

BSTR SayHello() {
    return ::SysAllocString(L"Hello");
}
        [DllImport("DBReplicator.Lib.dll")]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static extern string SayHello();

Ich weiß immer noch nicht, wie ich es geschafft habe, chinesische Schriftzeichen zu bekommen.