2012-03-30 6 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; 
    } 
} 

위의 코드는 델리게이트를 함수 포인터에 마샬링하여 보여줍니다. 이것으로 콜백을 할 수있었습니다. 하지만 나중에 메모리가 손상됩니다. 도와주세요. 감사합니다대리자를 함수 포인터로 마샬링합니다.

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

왜이 질문에'c'' visual-C++'AND'C# -4.0' 태그를 붙였습니까? – Eregrith

답변

4

가비지 수집기가 실행되고 대리인 인스턴스를 삭제할 때 프로그램이 넘어갑니다. pfWatch 로컬 변수에 의해 한번 참조 된 것. 그러나 ReadImageFile()이 반환 될 때, 그 변수는 오래 전에 사라졌습니다. 콜렉터는 비 관리 코드가 보유한 참조를 볼 수 없습니다.

자신을 참조하고 수집자가 볼 수있는 곳에 보관해야합니다. pfWatch는 최소한 로컬 변수 대신 클래스의 필드 여야합니다. 정적 일 가능성이 있으므로 가비지 수집되지 않습니다. 네이티브 코드가 콜백을 중단하는 경우 스 니펫에서 명확하게 알 수 없습니다.

+0

C++/CLI에서 참조를 활성 상태로 유지하기 위해'gcroot' 템플릿을 사용할 수 있습니다. 위임의 마샬링을 수행하는 C++/CLI 래퍼를 작성한 다음 순수한 .NET 인 것처럼 C#에서 코드를 호출하는 것이 좋습니다. –

+0

감사합니다 :) – SHRI

관련 문제