C # DLL P / Invoke CallbackOnCollectedDelegate Ошибка - PullRequest
1 голос
/ 11 апреля 2011
 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 был обнаружен».Как я могу решить эту проблему

Ответы [ 2 ]

2 голосов
/ 11 апреля 2011
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 голос
/ 11 апреля 2011

Вы вызываете KeepAlive не для того объекта - коробочной копии значения AddressCodeLine.То, что вы хотите сохранить в живых, - это сам объект делегата OnCodeline.

Теперь KeepAlive поддерживает только живой объект, пока метод не вернется.Если делегат обратного вызова может быть вызван асинхронно, вы должны вместо этого ссылаться на делегата из поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...