public delegate int MFS100_CodeLineDelegate(int code, int docId, string codeline);
public event MFS100_CodeLineDelegate MFS100_CodeLine;
MFS100_CodeLineDelegate OnCodeline = new MFS100_CodeLineDelegate(MFS100_OnCodeLine);
AdressCodeLine = Marshal.GetFunctionPointerForDelegate(OnCodeline);
mfSetEvent((int)EventEnum.E_EVENT_CODELINE, AdressCodeLine.ToInt32());
object cl = (object)AdressCodeLine;
GC.KeepAlive(cl);
[DllImport("mflib.dll")]
public static extern int mfSetEvent(int eventID, int callsback);
*Global variable*
private static IntPtr AdressCodeLine;
我将代理内存地址发送到dll以设置设备,当我从dll收到回调时,我得到错误:“检测到CallbackOnCollectedDelegate”。我该如何解决这个问题
答案 0 :(得分:2)
GC.KeepAlive("your Delegate instance").
或
you could store your delegate instance on a global variable.
编辑1:
看下面的代码,你会弄明白我的意思
public class CallbackDemo
{
//Don't forget to change the calling convention accordingly
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int MFS100_CodeLineDelegate(int code, int docId, string codeline);
public event MFS100_CodeLineDelegate MFS100_CodeLine;
//this is one method how you keep your delegate instance being collected by GC
private readonly MFS100_CodeLineDelegate cache;
public CallbackDemo()
{
cache = OnCallBack;
}
protected virtual int OnCallBack(int code,int docId,string codeline)
{
if(this.MFS100_CodeLine!=null)
{
MFS100_CodeLine(code, docId, codeline);
}
return 0;
}
[DllImport("mflib.dll")]
private static extern int mfSetEvent(int eventID, MFS100_CodeLineDelegate callsback);
private MFS100_CodeLineDelegate myDelegate;
public void CallSetEvent(int eventId)
{
mfSetEvent(eventId, this.cache);
}
}
答案 1 :(得分:1)
你在错误的对象上调用KeepAlive--一个AddressCodeLine值的盒装副本。你想要保持活力的是委托对象本身,OnCodeline。
现在,KeepAlive只保留对象,直到方法返回。如果可以异步调用回调委托,则应该从字段引用委托。