Jump to content
  • Advertisement
Sign in to follow this  
mazzim0

[.net] Messaging between C# app and C++ DLL

This topic is 3985 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello! Here is the situation: I have a dll made by C++ and an application made by C#. I'm trying to achieve that when I press the button in my C# applivation, it calls dll-function. This function will start a background thread which works on its own. When the background thread wants to inform the user, it will send a message to the main application. Application will handle the message and show some output to the user. In parts with some code: 1) User press the button - the application calls the dll:
[DllImport("myLib.dll", EntryPoint = "StartThread",
           ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public static extern void StartThread( [MarshalAs(UnmanagedType.LPStr)] string filename,
IntPtr hwnd );

///////////

private void MyButton_Click(object sender, EventArgs e)
{
     ((Button)sender).Enabled = false;
     StartThread( "myfile.txt", this.Handle );  // pass app handle to message sender
}
2) My dll starts the thread:
// some dll code (c++)
#define __MSG_EXIT__ 0xFF321F2

struct Settings
{
	std::string  filename;
	HWND  host_hwnd;		// the handle received from application
};

/** GLOBAL SETTINGS! */
Settings* gSettings = 0;




/** INTERNAL THREAD FUNCTION */
DWORD WINAPI __internel_ThreadFunc(LPVOID lpParam) 
{
	while(1)
	{
	// DO SOME FUN STUFF INSIDE THIS THREAD...
	}


	// THIS IS IMPORTANT!!!! SEND THE ENDING MESSAGE!
	SendMessage( gSettings->host_hwnd, __MSG_EXIT__, NULL, NULL );

	// THIS IS ONLY FOR TESTING
	::MessageBoxA( NULL, "SUCCESS!", "", MB_OK );

	return 0; 
} 


extern "C" __declspec(dllexport) void StartThread(const char* fname, HWND hwnd)
{
	gSettings = new Settings();
	gSettings->filename = fname;
	gSettings->host_hwnd = hwnd

	// start the thread
	HANDLE thread = CreateThread( NULL, 
		0, 
		__internel_ThreadFunc,
		0,
		0, 
		NULL);
 
	if( thread == NULL ) { ExitProcess( 0 ); ::MessageBoxA( NULL, "FAIL!", "", MB_OK ); }
}
3) Let's handle the messages in my C# application:
const int __MSG_EXIT__ = 0xFF321F2;

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override void WndProc(ref Message m) 
{
     switch (m.Msg)
     {
          // CHECK THE EXIT MESSAGE
          case __MSG_EXIT__:
              // DO SOMETHING WITH THIS MESSAGE!
              break;
     }
     base.WndProc(ref m);
}
Well.. My problem is that my overrided WndProc doesn't receive the __MSG_EXIT__ at all. The messagebox (in the C++ codes internal_threadFunc) below the sending line occurs every time but my C# application doesn't receive the message. What have I done wrong? Could anyone tell me? Thanks for your help. I'm not a native English speaker so if you don't understand my writings, please tell me. I'll try to explain better. [Edited by - mazzim0 on January 12, 2008 10:49:36 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by mazzim0
/** INTERNAL THREAD FUNCTION */
DWORD WINAPI __internel_ThreadFunc(LPVOID lpParam)
{
while(1)
{
// DO SOME FUN STUFF INSIDE THIS THREAD...
}


// THIS IS IMPORTANT!!!! SEND THE ENDING MESSAGE!
SendMessage( gSettings->host_hwnd, __MSG_EXIT__, NULL, NULL );

// THIS IS ONLY FOR TESTING
::MessageBoxA( NULL, "SUCCESS!", "", MB_OK );

return 0;
}


This isn't the actual code is it? If so, that while loop will continue forever, which is why it never reaches the messaging part.

Otherwise, how about writing your own callback? Personally, nowadays I do whatever I can to avoid the winapi :P .

For example, pass a delegate from c# to c (the delegate gets marshalled to a function pointer, that c can use to call into c#. And pass another function pointer from c to c#, marshal it to a delegate, and use that to call from c# to c. Simple :)

Share this post


Link to post
Share on other sites
Quote:
Original post by gharen2
This isn't the actual code is it? If so, that while loop will continue forever, which is why it never reaches the messaging part.

Otherwise, how about writing your own callback? Personally, nowadays I do whatever I can to avoid the winapi :P .

For example, pass a delegate from c# to c (the delegate gets marshalled to a function pointer, that c can use to call into c#. And pass another function pointer from c to c#, marshal it to a delegate, and use that to call from c# to c. Simple :)


No. It's not the actual code. It just demostrates the structure of my thread function.

I have thought about callbacks but I prefer this "traditional" way because of several little issues, which I didn't mention. Thanks anyway.

However.. I solved my problem. I had to register my message id (__EXIT_MSG__) with RegisterWindowMessage before I sent the messages. I do it in the application and then pass the proper message ids to my dll.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!