views:

354

answers:

2

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

+1  A: 

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){m_data=n;}
    ~MyClass(){}
    int GetData(){return n;}
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.

Alex Farber
You miss an extern "C" in the wrapper functions.
Danvil
Danvil - this is what I wrote in the question note. Anyway, thanks, I really feel better now.
Alex Farber
+1  A: 

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
} 
Danvil
thanks to everyone, I hated to admit it but looks like there is no other way besides writing a wrapper.