Hallo an alle Leser dieses Forums!
Ich versuche einen C# Delegate über eine managed C++ Wrapper-Klasse an eine unmanaged C++ Bibliothek zu übergeben, die den Delegaten als Callback Funktion aufruft. Leider kommt es beim Verlassen des Gültigkeitsbereiches meiner C# Callback-Funktion zu einem Laufzeitfehler (Win 32 Ausnahme). Kann hier trotz des noch gültigen GCHandle-Objektes eventuell der Funktionszeiger durch den Garbage Collector abgeräumt werden? Was könnte noch die Ursache für so einen Fehler sein?
Ausschnitt der Datei Ranger_D.h (managed):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
| public ref class Ranger_D { public: void setCallbackPointer(IntPtr ptr);
protected: IntPtr callback_ptr; GCHandle gch;
}
Ausschnitt der Datei Ranger_D.cpp (managed):
void Ranger_D::setCallbackPointer(IntPtr ptr) { callback_ptr = ptr; }
int Ranger_D::initFrameGrabber() { FrameGrabber::CallbackType cb = static_cast<FrameGrabber::CallbackType>(this->callback_ptr.ToPointer()); prms->setCallback(cb);
}
Ausschnitt der Datei SickRangerD.cs:
namespace ScannerLibrary.Impl { public class SickRangerD : LaserScannerDevice {
#region attributes protected delegate void ProfileReceiveMethod(IntPtr iconBuffer, IntPtr frameGrabber, uint userData); protected ProfileReceiveMethod profile_handler = null; protected Ranger_D ranger; protected GCHandle gch;
#endregion
public SickRangerD() { profile_handler += new ProfileReceiveMethod(ProfileEvent); init(); }
private void init() { ranger = new Ranger_D(); ProfileReceiveMethod^ fp = gcnew ProfileDelegate(ProfileEvent); gch = GCHandle.Alloc(fp); ranger.setCallbackPointer(Marshal.GetFunctionPointerForDelegate(fp));
} protected void ProfileEvent(IntPtr iconBuffer, IntPtr frameGrabber, uint userData) { Console.Writeln("Aufruf managed Callback."); }
} |
Weiterhin weiß ich noch nicht, wie ich passend für den in der unmanaged Bibliothek definierten Typ
C#-Quelltext
1:
| typedef void(__cdecl * CallbackType )(IconBuffer *buffer, FrameGrabber *fg, void *userdata) |
die Argumente für meine C# Funktion definieren soll. Mit IntPtr lässt es sich erstmal compilieren, jedoch kann ich IntPtr nicht nach FrameGrabber* konvertieren, wollte ich irgendwelche Eigenschaften dises Parameters abfragen.
Gibt es außerdem noch eine Möglichkeit die Aufrufkonvention des C# Delegaten von __stdcall nach __cdecl zu ändern?
Vielen Dank im Vorraus für jede Hilfe!
Moderiert von
Kha: C#-Tags hinzugefügt