Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create unmanaged c++ object in c#

I have an unmanaged dll with a class "MyClass" in it. Now is there a way to create an instance of this class in C# code? To call its constructor? I tried but the visual studio reports an error with a message that this memory area is corrupted or something.

Thanks in advance

like image 376
Evgeny007 Avatar asked Apr 14 '10 11:04

Evgeny007


3 Answers

C# cannot create class instance exported from native Dll. You have two options:

  1. Create C++/CLI wrapper. This is .NET Class Library which can be added as Reference to any other .NET project. Internally, C++/CLI class works with unmanaged class, linking to native Dll by standard C++ rules. For .NET client, this C++/CLI class looks like .NET class.

  2. Write C wrapper for C++ class, which can be used by .NET client with PInvoke. For example, over-simplified C++ class:


    class MyClass()
    {
    public:
        MyClass(int n){data=n;}
        ~MyClass(){}
        int GetData(){return data;}
    private:
        int data;
    };

C API wrapper for this class:


    void* CreateInstance()
    {
        MyClass* p = new MyClass();
        return p;
    }

    void ReleaseInstance(void* pInstance)
    {
        MyClass* p = (MyClass*)pInstance;
        delete p;
    }

    int GetData(void* pInstance)
    {
        MyClass* p = (MyClass*)pInstance;
        return p->GetData();
    }

    // Write wrapper function for every MyClass public method.
    // First parameter of every wrapper function should be class instance.

CreateInstance, ReleaseInstance and GetData may be declared in C# client using PInvoke, and called directly. void* parameter should be declared as IntPtr in PInvoke declaration.

like image 155
Alex F Avatar answered Nov 17 '22 21:11

Alex F


The solution is create C++/CLI wrapper like:

#include "DllExportClass.h"

public ref class ManagedOperationHelper
{
    public:

    double Sum(double add1, double add2)
    {
        CDllExportClass obj;
        double ret=obj.Sum(add1, add2);
        return ret;
    }

    double Mult(double mult1, double mult2)
    {
        CDllExportClass obj;
        double ret=obj.Mult(mult1, mult2);
        return ret;
    }
};

where CDllExportClass is the class exported from native code. Above is the .h of the C++/CLI. Take care to let find the lib to this dll. Put the dll and the lib in the same directory and compile the C++/CLI code.In the managed code directory put the native dll and the C++/CLI dll. In the managed project put the reference of the C++/CLI project. Instanciate in the maged code the C++/CLI class like:

ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);  

It's all.

like image 3
Gian Luca Tanda Avatar answered Nov 17 '22 22:11

Gian Luca Tanda


You can not use unmanged C++ code directly in C#. The interoperability can be done using PInvoke. There are a lot of issues related to this topic, especially when calling functions which have pointers as arguments.

The basic procedure goes like this:

C# part

namespace MyNamespace {
  public class Test {
    [DllImport("TheNameOfThe.dll")]
    public static extern void CreateMyClassInstance();

    public void CallIt() {
        CreateMyClassInstance(); // calls the unmanged function via PInvoke
    }
  }
}

C++ part

class MyClass {
  public: MyClass() { /** Constructor */ }
};

MyClass* staticObject;

extern "C" void CreateMyObjectInstance() {
   staticObject = new MyClass(); // constructor is called
} 
like image 2
Danvil Avatar answered Nov 17 '22 23:11

Danvil