How do I DllExport a C++ Class for use in a C# Application

Toymakerii picture Toymakerii · Jan 19, 2011 · Viewed 23.9k times · Source

I have created a C++ Dll project which contains a class "myCppClass" and tried to Dll export it using the following code as described by: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx

class __declspec(dllexport) CExampleExport : //public CObject
{ ... class definition ... };

I have omitted the "public CObject" as that requires afx.h and implies it is an MFC Dll. I am not sure if this is a good thing or not but it differed from the DLL project default settings.

From the above linked documentation I am led to believe that all "public functions and member variables" are available for import. How do I accomplish this in C#? Can simply instantiate the class?

Edit: I just realized that the Title of the post may be misleading. The emphasis should be on DllImport-ing from C# and ensuring that I followed the documentation properly in C++

Answer

Zooba picture Zooba · Jan 19, 2011

C# cannot directly import C++ classes (which are effectively name-mangled C interfaces).

Your options are exposing the class via COM, creating a managed wrapper using C++/CLI or exposing a C-style interface. I would recommend the managed wrapper, since this is easiest and will give the best type safety.

A C-style interface would look something like this (warning: untested code):

extern "C" __declspec(dllexport)
void* CExampleExport_New(int param1, double param2)
{
    return new CExampleExport(param1, param2);
}

extern "C" __declspec(dllexport)
int CExampleExport_ReadValue(void* this, int param)
{
    return ((CExampleExport*)this)->ReadValue(param)
}

A C++/CLI-style wrapper would look like this (warning: untested code):

ref class ExampleExport
{
private:
    CExampleExport* impl;
public:
    ExampleExport(int param1, double param2)
    {
        impl = new CExampleExport(param1, param2);
    }

    int ReadValue(int param)
    {
        return impl->ReadValue(param);
    }

    ~ExampleExport()
    {
        delete impl;
    }
};