2012-03-30 8 views
0
public class SendImage 
{ 
    public delegate int DWatch(int bytesLeftToSend, IntPtr Response); 
    ret=0xffff; 

    public void ReadImageFile() 
    { 
     int len = 1495; 
     DWatch pfWatch = DResponse; 
     IntPtr pfMethod = Marshal.GetFunctionPointerForDelegate(pfWatch); 
     ret=Send(len, pfMethod); 
    } 

    public int DResponse(int bytesLeftToSend, IntPtr Response) 
    { 
     //something; 
     return 0; 
    } 
} 

Der obige Code zeigt das Marshalling von Delegaten in Funktion Zeiger, wie ich es tat. Von diesem konnte ich zurückrufen. Aber später bekomme ich Speicherfehler. Bitte helfen Sie. DankMarshal-Delegat an Funktionszeiger: Speicher beschädigt

//unmanaged call in code 
int Send(int length, int(*pfMethod)(int bytesLeftToSend, void * Response)) 
{ 
    int Remaining = 50; 
    pfMethod(50); 
} 
+1

Warum haben Sie diese Frage markiert? '' 'Visual-C++' UND 'C# -4.0' – Eregrith

Antwort

4

Ihr Programm wird umfallen, wenn der Garbage Collector läuft und löscht die Delegate-Instanz. Dasjenige, das einmal von Ihrer lokalen Variablen pfWatch referenziert wurde. Aber nicht mehr, diese Variable ist lange weg, zappt, wenn ReadImageFile() zurückgegeben wird. Der Kollektor kann keine Referenzen sehen, die von nicht verwaltetem Code gehalten werden.

Sie müssen selbst eine Referenz aufbewahren und sie an einem Ort aufbewahren, den der Kollektor sehen kann. pfWatch muss mindestens ein Feld in Ihrer Klasse anstelle einer lokalen Variablen sein. Möglicherweise statisch, sodass niemals Müll gesammelt wird. Es ist ansonsten nicht klar aus Ihrem Snippet, wenn der native Code keine Callbacks mehr ausführt.

+0

Aus C++/CLI können Sie einfach die' gcroot' Vorlage verwenden, um die Referenz am Leben zu erhalten. Ich schlage vor, einen C++/CLI-Wrapper zu schreiben, der das Delegieren des Delegierten durchführt, und dann den Code aus C# aufruft, als ob es reines .NET wäre. –

+0

Vielen Dank allot :) – SHRI

Verwandte Themen