P/Invoking C++ callback functions crashes when .NET application is not in focus

0.00 avg. rating (0% score) - 0 votes

A C++ DLL exports one function having its only parameter as a pointer to another function:


#define AFX_EXT_CLASS __declspec(dllexport)
typedef void (CALLBACK* CALLBACKFUNC)(INT param1);
AFX_EXT_CLASS INT
TestCallback(CALLBACKFUNC lpCallback);

INT TestCallback(CALLBACKFUNC lpCallback)
{
MessageBox(GetActiveWindow(), L“Press OK to make the callback”, L“Testing”, MB_OK);
lpCallback(1);
}


From .NET code, P/invoke the function TestCallback()


Public Delegate Sub MyCallback(ByVal param1 As Integer)

<DllImport(DllName)> _
Public Function TestCallback(ByVal lpCallback as MyCallback) As Integer
End Function

Public Function MyCallbackFunc(ByVal param1 As Integer) As Integer
MessageBox.Show(“Callback works. Param = ” + param1.ToString)
End sub

TestCallback(AddressOf MyCallbackFunc)


It seems to work fine for a while. However, if the C++ function TestCallback calls lpCallback() when the .NET application does not have focus, or after it’s been running for sometime, the .NET application will crash.


The reason is probably that the callback delegate has been garbage collected and the function pointer that was passed to unmanaged code has been invalidated. You have to ensure that the delegate is alive for as long as the function pointer is used, by holding a reference to it. This means you can’t create the delegate inline in the same way it’s done in the above code sample:


TestCallback(AddressOf MyCallback) ‘VB.NET

TestCallback(new MyCallback(MyCallback) //C#

The correct declaration would be:

Dim MyCallbackEvent As MyCallback = AddressOf CallbackHandler
TestCallback(MyCallbackEvent)


It is advised to keep these delegate as global variables, otherwise GC.Collect() and GC.KeepAlive() may be needed

0.00 avg. rating (0% score) - 0 votes
ToughDev

ToughDev

A tough developer who likes to work on just about anything, from software development to electronics, and share his knowledge with the rest of the world.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>