Click here to Skip to main content
Click here to Skip to main content

IPC Between Managed and Unmanaged Code

, 15 Aug 2006
Rate this:
Please Sign up or sign in to vote.
An article about bridging the communication gap between managed and unmanaged code.

Introduction

Technology keeps leaping forward at a fast pace; applications in projects, large or small, normally cannot keep up with this speed. On one hand, it doesn't make sense to port old code to the new state merely for the status; on the other hand, it also isn't efficient not to use the modern technologies for new designs. Hence, what we get is a mixture of 'old' and 'new' stuff, or as Microsoft depicts it: the Managed and Unmanaged world, creating a new problem when both worlds have to communicate.

There exists, of course, the well-known Inter Process Communication -IPC-, the Microsoft Windows operating system mechanism for facilitating communication and data sharing between applications. This, however, is mainly a property of the old world; the .NET framework does not support such a thing, up till version 2.0. Even then, it is still a question whether it is usable for communication with the old world, or that it is only meant for inter-.NET-communication.

The solution presented here solves this cross-platform problem in a fairly easy and, most of all, simple way, using straightforward methods. Once this path is established, we can also do, for example, .NET Remoting between different machines where one of them is running a legacy MFC application as the object to be communicated with.

Background

Many articles have been written around this IPC topic; the one written by Venkat Raman, called "IPCWorkshop" is quite instructive with respect to the availability of the various communication methods, like MailSlots, NamedPipes, Sockets etc.

Using the code

As said above, the used scheme is very straightforward and easy to understand. The solution consists of two projects: "IPCinCSharp" containing the overridden System.Control.WndProc method, and "SendPostMessageInCSharp" which emulates a VC6-MFC application, firing up the PostMessage event. This emulation is done for simplicity of this article source and demo downloads - it is, of course, possible to use a real VC6 application for this part.

IPCinCSharp

This project does the 'listening to the Operating System messages'; it dispatches the incoming messages identified in the message structure. A threesome switch case is used for the experiment. The WM_MOUSEWHEEL operating system message is handled in this example to know when the user rolled the wheel within the application window area. The WM_APP+number case shows the actual managed-unmanaged base communication stuff: receiving and extracting the WParam and LParam arguments of the Win32-PostMessage function as sent by the "SendPostMessageInCSharp" application.

case WM_MOUSEWHEEL:
    MessageBox.Show("WM_MOUSEWHEEL invoked!");
    break;

case WM_APP+7232:
    int nWParam = m.WParam.ToInt32();
    int nLParam = m.LParam.ToInt32();
    MessageBox.Show("WM_APP message detected: " + m.Msg +
        "\r\nWParam=" + nWParam + " LParam=" + nLParam);
    break;

SendPostMessageInCSharp

This part of the code does the emulation of the VC6-MFC application, doing a PostMessage event after finding the target window. Due to the emulation, there are some (irrelevant) part of code in it, like the P/Invoke DllImport, responsible for calling the Win32 API function of PostMessage.

int nHandle = Win32.FindWindow(null,strAppName);
if (nHandle == 0)
{
    return WindowNotFound;
}
else
{
    int nMsg = Win32.PostMessage(nHandle, 
               nWM_APP, nX, nY); // Fire and Forget ....!
    return AllRight;
}

The Win32 P/Invoke part:

public class Win32
{
    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName, 
                                        string lpWindowName);
    [DllImport("user32.dll")]
    public static extern int PostMessage(int hWnd, uint Msg, 
                                         int wParam, int lParam);
}

The following code snippet can be input into your VC6-MFC application as a button control notification handler code (for the sake of completeness):

HWND hWndTargetWindow;
UINT msg=40000;
UINT wParam=123;
UINT lParam=456;

CString sCaption="SEARCHING Untitled";

if (::FindWindow(NULL, " - Untitled"))
{
    hWndTargetWindow = ::FindWindow(NULL, " - Untitled");
    PostMsg(hWndTargetWindow, msg, wParam, lParam);
    MessageBox("Untitled Window FOUND!", sCaption, MB_ICONEXCLAMATION);
}
else
{
    MessageBox("ERROR in FindWindow execution!", sCaption, MB_ICONERROR);
}

That's all there is. Have fun.

History

  • August 2006 - This is my first CodeProject submission - please be kind.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

wiet lie
Web Developer
Netherlands Netherlands
No Biography provided

Comments and Discussions

 
GeneralSpecific approach PinmemberMilind Shingade13-Nov-07 1:40 
GeneralRe: Specific approach Pinmemberwiet lie15-Nov-07 13:26 
The article discusses a 'low-cost', simple way of communicating bits of information in its most basic manner, as what it is primarily the intention is for the WPARAM and LPARAM 32 bits values. It is used to pass things like handles and integers. As such, this command message structure isn't meant to be a universal-carry-any-data thing.
 
Having stated that, I'll cover your string issue:
 
Manipulating strings is not a trivial job to do as you can read it yourself in the following article of Dr.Dobb's Generalized String Manipulations
(http://www.ddj.com/cpp/184401689).
Also worth reading is: http://www.flounder.com/csharpfactoids.htm, where Joseph Newcomer elaborates extensively on the topic of "C# for MFC programmers", providing quick equivalents map.
 
How to convert CString class to equivalent class in C#?
Well,I can't give you a direct answer ... perhaps juggling around with P/Invoke (get your stuff in the Managed world) and then dive into the rich C# classes like StringReader, StringBuilder, StringFormat, StringCollection, and so on.
Mind you though, that CString is a special C++ object, containing a pointer to a buffer, a count of the valid chars in that buffer, and the buffer length value.
There exist, to some extend, equivalents of MFC in C#, like: the C# equivalent of CString::Find is IndexOf.
You could write a wrapper for the C++ library in Managed C++, which will convert the CStrings to System.Strings. However, my best estimate is using the P/Invoke manner.
 
'Dotnet247.com' does also contain articles addressing your question, please take a look in there.
 
Good luck!
--------------
ps: did you vote ....?

GeneralRe: Specific approach PinmemberEricF4-Apr-08 15:42 
QuestionCan u Help Me? PinmemberEsonix20-Feb-07 0:44 
AnswerRe: Can u Help Me? Pinmemberwiet lie21-Feb-07 23:02 
QuestionHow to use structures for wParam and lParam? PinmemberDieter Geers10-Nov-06 5:57 
AnswerRe: How to use structures for wParam and lParam? Pinmemberwiet lie13-Nov-06 2:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 15 Aug 2006
Article Copyright 2006 by wiet lie
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid