Managed Calls and Events in Unmanaged C++

Managed Calls and Events in Unmanaged C++

Nowadays, most of the developers and companies want to immigrate to .NET. But, the question still is, how do you implement the new components written in .NET in the old applications: Win32, MFC…. In this article, I will explain how to develop an application in .NET and how to use it even in a simple C++ application.

I hope after that, reading this article, it will be easy for you to navigate between the managed and unmanaged worlds.

Create a “Class Library” project and name it “MyManagedSide”.

First of all, add using System.Runtime.InteropServices; to your class to support COM interop. And, to enable a managed code to be used from an unmanaged one, you have to register your .NET application as COM. As you may know, COM must expose some interfaces.

Declare a very simple interface and use a GUID tool to create a GUID in the Registry format.


[Guid(“3E0E2EB2-CC13-40fb-9346-34809CB2419C”)]
public interface IMyManagedInterface
{
void SayHello();
}

The interface will be implemented in the MyManaged class. You also create a GUID for the MyManaged-class.


[ClassInterface(ClassInterfaceType.None)]
[Guid(“946B4230-33E9-4fd9-8F71-EFBE5E0C2CF2”)]
public class MyManaged : IMyManagedInterface
{
public MyManaged()
{
}

//implementation of the interface method
public void SayHello()
{
MessageBox.Show(“Welcome to the wonderful world of .NET” );
}
}

[ClassInterface(ClassInterfaceType.None)] indicates that no class interface is generated for the class.

Create a strong name with the command: Sn -k MyManaged.snk and set it in your project settings.

Set the option “Make assembly COM-Visible” in your project settings.

Build your application.

Use the command gacutil.exe" /i MyManagedSide.dll to store your assembly in the GAC. Use the command RegAsm MyManagedSide.dll /tlb:com.MyManagedSide.tlb to register you assembly. After registering your assembly can be used from any COM client. RegAsm is like regsvr32.

MFC client

Create an MFC Project (Dialog based). Select “MFC Class from TypeLib”.

Select MyMangedSide from the list and add IMyManagedInterface.

Add CMyDotNetInterface as a member variable to your dialog class and make the following changes:


BOOL CTestComMfcDlg::OnInitDialog()
{
. . .
// TODO: Add extra initialization here

if(!AfxOleInit())
{
AfxMessageBox(_T(“Could not initialize COM services”));
return FALSE;
}

//static const CLSID clsid = {0x946b4230,0x33e9,0x4fd9,
//{0x8f,0x71,0xef,0xbe,0x5e,0x0c,0x2c,0xf2}};
//m_MyManagedInterface.CreateDispatch(clsid );
//or
//lpszProgID = “MyManagedSide.MyManaged”
m_MyManagedInterface.CreateDispatch(_T
(“MyManagedSide.MyManaged”)));

//call managed interface
m_MyManagedInterface.SayHello();

return TRUE;
}

C++ client

Create an empty console project and make the following changes:


//importing the type library
#import “.. \\com.MyManagedSide.tlb”

void main()
{
//Initialize the COM library
CoInitialize(NULL);

//Get the pointer to your .NET Interface and create a new
//instance
MyManagedSide::IMyManagedInterfacePtr pMyManagedInterfacePtr;
HRESULT hRes = pMyManagedInterfacePtr.CreateInstance
(MyManagedSide::CLSID_MyManaged);

if (hRes == S_OK)
{
//Call your .NET method:
pMyManagedInterfacePtr->SayHello();
}

CoUninitialize ();
}

More by Author

Must Read