C3374: kann nicht Adresse von ‚Funktion‘ übernehmen, es sei denn Delegatinstanz Schaffung

StackOverflow https://stackoverflow.com/questions/822582

  •  03-07-2019
  •  | 
  •  

Frage

Ich habe Schwierigkeiten, eine Bibliothek von Drittanbietern Registrierungsfunktion mit einem Rückruf zu registrieren. Ich schreibe in C ++ CLI und Bibliothek geschrieben in C oder C ++ zugreifen.

Was bedeutet der oben Compiler-Fehler bedeuten?

Dies ist die Registrierungsfunktion wie vom Hersteller definiert:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);

Dies ist der Rückruf als vom Hersteller definiert:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);

Meine Callback-Funktion:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

Mein Anruf (die nicht):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);
War es hilfreich?

Lösung

Wenn ich eine Vermutung wetten hatte, Sie versuchen, die Adresse einer MANAGED Funktion genommen und es als NATIVE Funktionszeiger übergeben. Das wird nicht funktionieren. Entweder schreiben eine native Brücke (härter und wahrscheinlich kein Vorteil) oder (und das ist der einfache Ansatz), einen Delegaten erstellen und verwenden Marshal.GetFunctionPointerForDelegate . Vergessen Sie nicht, dass der Beauftragte für die Dauer am Leben zu bleiben hat, dass der native Code erwartet zurückrufen, so dass Sie am ehesten benötigen irgendwo zu speichern.

Oh, und alle Funktionen in einer ref-Klasse oder Wertklasse sind Funktionen verwaltet werden, für den Fall, dass nicht klar ist.

[EDIT] Antwort Expanding Fragen in den Kommentaren zu decken. Der erste Schritt ist es, einen passenden Delegierten zu erstellen. Für die Funktion, die Sie zur Verfügung gestellt, es wird wie folgt aussehen:

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);

Dann müssen Sie erstellen:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

Und wie bereits erwähnt, sollten Sie die in Ihrer Klasse als Mitglied, um zu speichern, um sicherzustellen, dass es nicht verschwindet. Schließlich müssen Sie die Funktionszeiger zu erhalten und es weitergeben:

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);

Ich denke, dass alles abdeckt. Alles, was Sie brauchen, ist using namespace System; und Sie sollten in Ordnung sein.

Andere Tipps

Ihr Rückruf func ist Mitglied - Zeiger auf Mitglieder und Zeiger auf Funktionen sind verschiedene Dinge

.

Auch in Promit Lösung:

CallbackFuncDelegate(CallbackFunc)

callbackFunc sollte nicht sein Klassenmember

Sie können einfach schreiben

public ref class Device 
{
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

und verwenden Sie dann

Device::CallBackFunc
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top