Mapping IntPtr in Struct über Marschall.PtrToStructure verursacht "Zugriffsverletzung-Ausnahme"

Ich versuche, verwenden Sie eine C++ - DLL (3rd-party-Bibliothek der Umsetzung EMI-Protokoll, mit source-code verfügbar).NET. Ich habe erfolgreich getan marshalling Aufruf der Funktionen und alles funktioniert Prima.

Tritt das problem auf, wenn ich will, zu tun marshalling von Typ IntPtr zurück in die .NET Struct , hier ist der code (modifiziert, wie vorgeschlagen entfernt "ref" und verändert die AllocHGlobal zu reservieren, nur die Größe der emiStruct) :

private EMI emiStruct;
private IntPtr emiIntPtr;

emiIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(emiStruct));
Marshal.StructureToPtr(emiStruct, emiIntPtr, false);
EMIStruct.Error result = emi_init(emiIntPtr, hostname, portNumber, password, shortNumber, windowSize, throughput);
Marshal.PtrToStructure(emiIntPtr, emiStruct);

Die Letzte Zeile (PtrToStructure) führt zu einer Ausnahme "Versucht, Lesen oder schreiben von geschütztem Speicher. Dies ist Häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist".

Ich kann auch sehen, eine debug-Ausgabe:

A first chance exception of type 'System.AccessViolationException' occurred in mscorlib.dll
First-chance exception at 0x7c970441 in XXXXX.exe: 0xC0000005: Access violation reading location 0xc3fffff8.
First-chance exception at 0x7c970441 in XXXXX.exe: 0xC0000005: Access violation reading location 0x01fffff7.
First-chance exception at 0x7c970441 in XXXXX.exe: 0xC0000005: Access violation reading location 0x00001f1d.

Ich nehme an, das problem ist irgendwo in der Zuweisung von Speicher für den Zeiger emiIntPtr. Obwohl, wenn ich den code auszuführen, und es ist ein problem mit der Verbindung zum server (z.B. server nicht gefunden), folgte die Einweisung auf die Struct emiStruct richtig gemacht (keine Ausnahme). Das problem tritt nur auf, wenn die Verbindung erfolgreich eingerichtet und den server senden reagieren.

Auch, schrieb ich ein C++ - Beispiel-app mit dem gleichen DLL-Bibliothek, die ich versuche zu verwenden .NET, und diese Anwendung (wenn ich es kompilieren) läuft Prima - es bedeutet, die C++ - DLL sollte in Ordnung sein und nicht die Ursache abstürzt.

Außerdem habe ich gefunden, einige Hinweise zu aktivieren/deaktivieren Sie verschiedene Eigenschaften für das Projekt compilator (mit JIT-Compiler kompiliert für x86 cpu, etc.), leider nichts von alledem geholfen.

Haben Sie irgendeine Idee, wo das problem liegen könnte oder wie man eine korrekte IntPtr inicialization in .NET und Zuordnung zwischen IntPtr und Struct?

Danke an alle für Ihre Antworten:

Hier bin ich dem hinzufügen des C++ - header der emi_init func:

FUNC( init)( EMI*           emi,         /* out */
const char*    hostname,    /* in  */
unsigned short port,        /* in  */
const char*    password,    /* in  */
const char*    origin_addr, /* in  */
int            window_sz,   /* in  */
         int            throughput); /* in  */

Und hier ist der C# - emi_init Erklärung (ich habe entfernt die "ref" - Attribut für emiPtr wie vorgeschlagen wurde):

[System.Runtime.InteropServices.DllImport("emi.dll", EntryPoint = "_emi_init")]
    public static extern EMIStruct.Error emi_init(
    System.IntPtr emiPtr,
    [System.Runtime.InteropServices.InAttribute()]  [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string hostname,
    ushort port,
    [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string password,
    [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string origin_addr,
    int window_sz, int throughput);

Jedoch noch immer die gleiche exception.

  • warum sind Sie vorbei an der ptr von ref? Das scheint seltsam. Wäre gut zu sehen der c++ - Header.
  • Heffernan: Interessante Stelle 🙂
  • Warum nicht Sie zeigen uns die C++ - Seite des interface?
InformationsquelleAutor Frankie | 2011-08-23
Schreibe einen Kommentar