Answered by:
Callback function from C# to C++

Question
-
Hello,
I have searched on the net, but I haven't found an answer to my problem.
I have a C++ program (an exe file) and a C# dll. The exe file contains a callback function. I need to send the pointer to the C# dll, in order to call the function back from C#.
Here is a scenario:
In the C++ file:
struct MSG_INFO
{
void* caller;
char* info;
long errnum;
};
void callback(MSG_INFO* info)
{
// do something
}
The C# dll should receive the pointer to the callback function from the exe and call it through this pointer. If I use managed C++ instead of C#, everything works perfect. I use .NET 2.0 and Visual Studio 2005.
A short C# sample of how to receive the pointer to callback function and how to call the function using the pointer would be great.
Thank you for any help/advice.Tuesday, November 20, 2007 7:01 AM
Answers
-
This is fairly simple to do. Just use the Marshal class to generate a delegate for the function. Y ou need to do only two things to get this to work.
1. Make sure that the structure has been correctly marshaled in your C# code. You should have a class that looks like this (I'm assuming that "caller" is a pointer to a object here; if this doesn't work, then it should after a little tweaking):
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]class MSG_INFO{[MarshalAs(UnmanagedType.LPStruct)]public IntPtr caller;[MarshalAs(UnmanagedType.LPStr)]public string info;[MarshalAs(UnmanagedType.I4)]public int errnum;}2. You need to create a delegate that takes a "pointer" to the structure you just created. You should be able to get away with this.
delegate void CallbackFunction(MSG_INFO msgInfo);3. The final step is to Marshal the pointer to a Delegate. This is fairly easy. I'm going to assume that you're getting a void pointer and start from there.
unsafe void InvokeCallback(void* callback, MSG_INFO msgInfo)That should work fine for you. If it doesn't, we can tweak it a bit. If you've got alot of these callbacks going on, I would suggest that you make/use a generic method for calling the callbacks.
{
IntPtr ptr = new IntPtr(callback);
CallbackFunction cbFunc = (CallbackFunction)Marshal.GetDelegateForFunctionPointer(ptr, typeof(CallbackFunction));
cbFunc(msgInfo);
}
Wednesday, November 21, 2007 12:12 AM
All replies
-
This is fairly simple to do. Just use the Marshal class to generate a delegate for the function. Y ou need to do only two things to get this to work.
1. Make sure that the structure has been correctly marshaled in your C# code. You should have a class that looks like this (I'm assuming that "caller" is a pointer to a object here; if this doesn't work, then it should after a little tweaking):
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]class MSG_INFO{[MarshalAs(UnmanagedType.LPStruct)]public IntPtr caller;[MarshalAs(UnmanagedType.LPStr)]public string info;[MarshalAs(UnmanagedType.I4)]public int errnum;}2. You need to create a delegate that takes a "pointer" to the structure you just created. You should be able to get away with this.
delegate void CallbackFunction(MSG_INFO msgInfo);3. The final step is to Marshal the pointer to a Delegate. This is fairly easy. I'm going to assume that you're getting a void pointer and start from there.
unsafe void InvokeCallback(void* callback, MSG_INFO msgInfo)That should work fine for you. If it doesn't, we can tweak it a bit. If you've got alot of these callbacks going on, I would suggest that you make/use a generic method for calling the callbacks.
{
IntPtr ptr = new IntPtr(callback);
CallbackFunction cbFunc = (CallbackFunction)Marshal.GetDelegateForFunctionPointer(ptr, typeof(CallbackFunction));
cbFunc(msgInfo);
}
Wednesday, November 21, 2007 12:12 AM -
I hate it when people give half ass solution. It is either they don't know how to do it or they assume people can read their mind.Tuesday, July 3, 2018 2:39 PM