0

I have a native function which accepts a pointer to function which should be called periodically throughout the lifetime of the process. This function is exported from the dll where it is defined.

Now, from managed code I want to call this function with my delegate as an argument. Also my delegate is a non-static one (it references this).

So:

    [UnmanagedFunctionPointer(CallingConvention.Winapi)]
    public delegate void MyDelegate([MarshalAs(UnmanagedType.LPWStr)] string myString);

    [DllImport("mydll")]
    public static extern int DelegateSet(MyDelegate);

    public void MyFunc(string myString)
    {
       // Do something here.
    }

    // Somewhere in managed code:
    DelegateSet(MyFunc);

And this works but only for the short time. Native code calls this callback a couple of times and then I hit an AV. My guess is that garbage collector moves the object which contains the delegate and native code has a loose reference.

I would appreciate any pointers on how to proceed.

Klark
  • 8,162
  • 3
  • 37
  • 61
  • The GC will destroy the delegate object, it cannot see it being used by native code. It is your job to keep it alive. Either store it in a *static* variable or use GCHandle.Alloc(). Do not set the variable back to null or call GCHandle.Free() until you are sure that the native code can no longer make the callback. – Hans Passant May 04 '16 at 17:37
  • My question is also what should I pin in this case - is it sufficient to just pin the delegate, or should I pin the *this* object which is reference by the delegate as well? – Klark May 04 '16 at 17:43
  • Only the delegate object. You are not creating it explicitly in your snippet, use variable = new MyDelegate(MyFunc); DelegateSet(variable); where *variable* is a static variable. – Hans Passant May 04 '16 at 22:14

0 Answers0