Click to See Complete Forum and Search --> : How to communicate between native c++ class and managed c++ (form) class
s196675m
March 18th, 2008, 12:05 PM
HI
I have a native c++ class which is responsible to open and process some filea. I want to display the status of the files in StatusBar of my winform. I tried to created delegate and event in native c++ class but it does not allow. It says unmanaged c++ classes not allowed to create managed event.
Is there any other way I can pass status information from native c++ classes to my form class.
I will appreciate your thought.
thank you.
Alex F
March 19th, 2008, 03:41 PM
If you need to make kind of event raised from unmanaged class and handled in managed class, use Marshal.GetFunctionPointerForDelegate method. Add callback function to managed class (notice that it can be regular class function, not static as required for unmanaged callbacks) and pass result of GetFunctionPointerForDelegate to unmanaged class. Inside of unmanaged class, cast it to function pointer of required type, and you have callback pointer.
I guess your class has its own "life" in some worker thread, in this case it makes sence to create callbacks. In this case, managed callback function is called from a worker thread, and you need to use Control.BeginInvoke or Control.Invoke to access UI elements.
See my last post here:
http://www.codeguru.com/forum/archive/index.php/t-444298.html
s196675m
March 20th, 2008, 02:41 PM
Hi Alex
I have read your link and tried to do the same thing.
your idea looks excellent but I have some difficuly to make it work in my way.
Just let me explain my situation:
I have declare a function pointer and one function to initialize a function pointer and another function to call this function pointer. All are in natice c++ .lib file
<code>
In Unmanaged library (.lib):
void (*dispp)(char* ch); // function pointer declaration
void DisplayStatus(char* str)
{
dispp(str);// calling function thru pointer
}
void InitializeFuncPtr(void (*func)(char* ch))
{
dispp = func;// Initializing the function pointer with the incoming one
}
void testFunc()
{
// Calling function pointer indirectly via DisplayStatus functon
DisplayStatus("Callback called");
}
</code>
This Display function will be used to pass any status information from any unmanaged function inside unmanaged lib.
Now in my managed form:
In Managed code:
I have declared a delegate outside of form class
public delegate System::Void callbackfunc(char* ch);
and a method inside of Form class as follows
public: void DisplayStat(char* ch)// simple function will be used as callback from unmanaged code
{
System::String^ str = gcnew System::String(ch);
System::Windows::Forms::MessageBox::Show(str);
}
and in one of the button_click event of managed form I have the following code
callbackfunc^ delegatefunc = gcnew callbackfunc(this,&GUI::Form1::DisplayStat);
System::IntPtr d1 = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(delegatefunc);
InitializeFuncPtr(( void(*)(char*))d1.ToPointer());// Calling unmanged library function to initialize function pointer
testFunc(); // Caling a test function from unmanaged library which will call function thru function pointer
It compiles fine but I got an error when managed function is called via function pointer stored in unmanaged code
=============
When I make the DisplayStat function as static and use &this->DisplayStat as an argument in InitializeFuncPtr, it works. I don't want static function because I can not pass the data I got to update the Form object.
Hopefully you can help to find my mistake.
Thank you and appreciate your help.
Alex F
March 20th, 2008, 03:47 PM
What error exactly?
s196675m
March 20th, 2008, 04:36 PM
This is the exact error message:
======================
Managed Debugging Assistant 'Reentrancy' has detected a problem in 'c:\Testing\GUI\Debug\testfpA.exe'.
Additional Information: Attempting to call into managed code without transitioning out first. Do not attempt to run managed code inside low-level native extensibility points, such as the vectored exception handler, since doing so can cause corruption and data loss.
=======================
When debugging, breakpoint stop to this line in the main functon:
Application::Run(gcnew Form1()); // breakpoint stops here
It looks like when Managed function call from unmanaged code via function pointer, it tried to create an another instance of the form class.
Thank you.
s196675m
March 20th, 2008, 05:03 PM
Hi Alex
I got the problem by following another thread.
I should declare function pointer with __stdcall.
Here is the correction with __stdcall convention
=================
In Unmanaged library (.lib):
void (__stdcall *dispp)(char* ch); // function pointer declaration
void DisplayStatus(char* str)
{
dispp(str);// calling function thru pointer
}
void InitializeFuncPtr(void (_stdcall *func)(char* ch))
{
dispp = func;// Initializing the function pointer with the incoming one
}
and in Managed code:
InitializeFuncPtr(( void( __stdcall *)(char*))d1.ToPointer());
Thank you Alex. Your thought led me to find the solution.
Good luck.
[BTW I could not find any way to make code appear bold or color. Only I see lot of icon I can choose from this editor]
darwen
March 20th, 2008, 07:16 PM
There is an alternative if you're working in C++/CLI :
See
http://www.codeguru.com/Csharp/.NET/net_general/patterns/article.php/c8381/
It's in managed C++ but the principle still applies.
Darwen.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.