Ich muss einen verwalteten Rückruf an einen nicht verwalteten TCP-Empfänger übergeben. Da es ein Thread ist, der für die Lebensdauer der Anwendung vorhanden sein muss, muss ich verhindern, dass der Müll gesammelt wird. Ich habe überall gelesen, dass Pinning Funktion Pointer nicht erforderlich ist und GCHandle.Alloc wird die Aufgabe, Garbage Collection zu verhindern.Pin einen Funktionszeiger
Aber ist das gegeben? Ich habe gesehen, dass der AppPool, der diesen Code hostet, mit einer Zugriffsverletzung abstürzt. Warum sollte ich nicht die Tatsache vermuten, dass dieser Fehler auftritt, weil der Funktionszeiger "Garbage Collection" war? Diese post unterstützt diese Tatsache.
Update: Dies scheint die Abstürze erheblich reduziert zu haben. Gibt es ein Problem mit diesem Ansatz?
typedef void (__cdecl *ProcMessageFunc)(void* param, void* paramBuf, ULONG bufSize);
FuncDelegate^ fp = gcnew MessageFuncDelegate(this, &Handler);
pin_ptr<MessageFuncDelegate^> pinnedFunctionPointer = &fp;
ret = Receiver ((ProcMessageFunc)pinnedFunctionPointer);
Das Delegate-Objekt in einer statischen Variablen zu speichern ist ausreichend. Nativer Code kann aus vielen anderen Gründen mit Zugriffsverletzungen bombardieren. –
Ich habe genau das getan. Der Grund, warum ich dazu tendiere, die Garbage Collection als Ursache zu verdächtigen, ist, dass die Zugriffsverletzung unregelmäßig auftritt. Und noch wichtiger ist der Aufruf-Stack im Crash-Dump Ich kann die native DLL sehen, gefolgt von der clr.dll und dann kernel32.dll an der Spitze des Stapels. Diese Reihenfolge ist konsistent. – Krishter