2 Stimmen

In welchen Fällen sollten Parameter bei einem P/Invoke-Aufruf angeheftet werden?

Ich habe eine DLL, aus der ich die folgende C-Methode P/Invoke muss:

int DAOpen(HANDLE *hOpen, UNIT *flags, void *callback, char *userData)

Ich habe mir die folgende C#-Signatur ausgedacht:

[DllImportAttribute("<libName>", EntryPoint="DAOpen")]  
    static extern  int DAOpen(  
    out IntPtr hOpen,  
    ref uint flags,  
    IntPtr callback,  
    IntPtr userData);

Angenommen, der native Code behält einen Verweis auf alle Parameter länger als die Dauer des P/Invoke-Aufrufs:

  1. Neben der Beibehaltung einer Instanz der hOpen Soll ich es auch anheften?

  2. Sollte ich einen Verweis auf die flags variabel? Sollte ich sie auch anheften, da sie in diesem speziellen Fall als Referenz übergeben wird?

  3. Ich weise meine callback auf folgende Weise zu delegieren:

    private IntPtr callBackOnNativeEvents;
    ...
    this.callBackOnNativeEvents = Marshal.GetFunctionPointerForDelegate(
    new CallBack(this.CallBackOnNativeEvents));

    Sollte ich einen Verweis auf den Delegaten an sich (nicht nur den Zeiger) behalten? Sollte ich ihn auch anheften?

  4. Schließlich definiere ich die userData auf die folgende Weise:

    private IntPtr userData;
    ...
    string userName = "test";
    this.userData = Marshal.StringToHGlobalAnsi(userName);

    Sollte ich einen Verweis auf die Zeichenfolge behalten? Sollte ich sie auch anheften? Die API-Dokumentation besagt, dass der Inhalt der Zeichenfolge in den nicht verwalteten Speicher kopiert wird, aber ich bin mir nicht sicher, ob auch der Inhalt des Verweises kopiert wird.

2voto

David Heffernan Punkte 585606
  1. Keine Stecknadel erforderlich hOpen hat sie eine Werttyp-Semantik.
  2. Wenn die DLL an die Adresse schreibt, auf die mit flags und dies tut, nachdem die ursprüngliche Funktion zurückgekehrt ist, dann müssen Sie sie auf die eine oder andere Weise festnageln (sowie sie am Leben erhalten und vor den Klauen der GC schützen).
  3. Der Zeiger auf die Callback-Funktion ist bereits effektiv fixiert. Sie müssen einen Verweis auf den Delegaten aufrechterhalten, aber Sie müssen ihn nicht anheften, da die nativer Thunk wird aus dem unveränderten Heap zugewiesen .
  4. Sie brauchen hier nichts Besonderes zu tun, da Sie eine IntPtr und die Erinnerung daran ist fest verankert. Es ist nicht notwendig, einen Verweis auf die Zeichenkette aufrechtzuerhalten, da sie vollständig von der Zeichenkette getrennt ist. IntPtr zurückgegeben von StringToHGlobalAnsi . Er hat lediglich eine Kopie des Inhalts der Zeichenkette zum Zeitpunkt des Aufrufs von StringToHGlobalAnsi .

Ich muss sagen, dass ich immer noch ungläubig bin, dass diese DLL wirklich das tun könnte, was Sie sagen, dass sie es tut. Ich vermute, dass etwas anderes schief läuft, was Sie falsch diagnostizieren, da die DLL Zeigerparameter von einem Aufruf festhält und dann ihren Inhalt bei nachfolgenden Aufrufen ändert. Es fällt mir außerordentlich schwer, das zu glauben, aber natürlich können nur Sie das wirklich wissen. An Ihrer Stelle würde ich die Frage einfach an den Hersteller der DLL stellen.

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