Google
WWW Yariv Hammer's Code Site

Sunday, October 23, 2005

Importing C++ Unmanaged class into .NET 2003

Introduction
There are several ways of using unmanaged code in C# and VB.NET. The most common approach is the use of dllimport, and is frequently used when using WinAPI32 - You declare the function you want to use by declaring the managed signature, which is equivalent with the unmanaged signature, and use the method as you would any other managed function.
The problem with this approach is the lack of OO. We are importing functions, not classes, and this is really an old fashioned approach. What if we have an MFC class we want to use? Or a complex class we have implemented.

A Solution
I will present one way of importing unmanaged classes. You will need the header files of the unmanaged code as well as the compiled unmanaged product.

Two steps must be followed:
1. Create a wrapper in C++ Unmanaged code from inside VS .NET environment.
2. Create a wrapper in C++ managed code for the wrapper from the first step.
When I say "wrapper" I mean a class that has the same interface of the original class, and implements all functions simply by calling the corresponding functions from the original class.
It is obvious that you can change the interface if you really want to, but for the beginner of us we will keep the same interface.

Lets say the original class looks like this:
-------------------------------------------

class __declspec(dllexport) MyUnmanagedVC6Class
{
public:
   MyUnmanagedVC6Class(int);
   void DoSomething(int,double);
}

-------------------------------------------

and it is located in MyUnmanagedVC6Header.h file, which we have.
Step 1

Now we open a blank solution, and add a new C++ MFC Class Library Project. Lets call it MyUnmanagedDotNetVCWrapper. We will implemenet a wrapper for MyUnmanagedVC6Class:
-------------------------------------------

#include "MyUnmanagedVC6Header.h"
class __declspec(dllexport) MyUnmanagedDotNetClass
{
private:
   MyUnmanagedVC6Class* _class;
public:
   MyUnmanagedDotNetClass(int x)
   {
      _class = new MyUnmanagedVC6Class(x);
   }
   void DoSomething(int x,double d)
   {
      _class->DoSomething(x,d);
   }
}

---------------------------------------------
This should be located in MyUnmanagedDotNetHeader.h.
Notice: If you have all the sources for the original dll you can open it in VisualStudio .NET, and it will convert it for you into a dll you can use for the next step. This can save you the time for the first wrapper.

Step 2
we add to the solution (it has to be the same solution) a new project: MFC C++ project, again unmanaged. Lets call it MyManagedDotNetVCWrapper. Now we right click on the name of the new project, and we change the property "Use Manage Extensions" to "Yes". This causes it to be like a managed environment (not exactly the same, but for our purposes this is what we need).
Now we add a reference to the dll we created in step 1: RightClick on References, and then choose "Add References". On the Projects Tab, choose the MyUnmanagedDotNetVCWrapper.dll .Now we add a new header to the project, called MyManagedDotNetHeader.h, with a class:
-------------------------------------------------------

#include "MyUnmanagedDotNetHeader.h"
namespace MyWrapperNamespace
{
   public __gc class MyManagedDotNetClass
   {
   private:
      MyUnmanagedDotNetClass __nogc * _class;
   public:
      MyManagedDotNetClass(int x)
      {
         _class = new MyUnmanagedDotNetClass(x);
      }
      void DoSomething(int x, double d)
      {
         _class->DoSomething(x,d);
      }
   };
}

-------------------------------------------
Notice the __gc (Garbage Collection) flag on the managed class, and the __nogc flag on the unmanaged pointer. Also notice the use of the namespace.
After you build this, you can now use the MyManagedDotNetVCWrapper.dll in all your managed projects, like C# and VB.NET, by adding a reference to it.

0 Comments:

Post a Comment

<< Home

Feel free to use everything here. Add links to my site if you wish.

Do not copy anything to other sites without adding link to here.

All the contents of the site belong to Yariv Hammer.