Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export a C++ class library to C# using a dll?

Tags:

c++

c#

import

dll

In my previous revision game engine I deported major functions for the game editor for C#. Now, I'm beginning to revise the game engine with a static library. There's a already dynamic library created in C++ to use DLLEXPORT for C#. Just now I want to test out the newer functions and created a DLL file from C++. Because the DLL contains classes I was wondering how would I be able to use DLL Export. Would I do this:

[DLLEXPORT("GameEngine.dll", EntryPoint="SomeClass", Conventional=_stdcall)]
static extern void functionFromClass();

I have a feeling it's probably DLLImport and not DLLExport. I was wondering how would I go about this? Another way I was thinking was because I already have the DLL in C++ prepared already to go the C# Class Library. I could just keep the new engine as a lib, and link the lib with the old DLL C++ file.

Wouldn't the EntryPoint be able to point to the class the function is in?

like image 498
SICGames2013 Avatar asked Mar 22 '23 16:03

SICGames2013


2 Answers

You can't actually export C++ classes directly like this.

static extern void functionFromClass();

The problem with C++ is that it doesn't have a universally defined ABI (Application binary interface). So In order to make other languages understand your C++ library ABI you need to wrap it with C functions (almost every other language understands C).

The problem with C is that it doesn't understand classes. On the other hand, C++ Objects need to pass this pointer as a parameter to their member functions. So in order to wrap your C++ classes with C interface. You need to handle passing this parameter explicitly and also define functions similar to the constructor and destructor.

You need to do sth like this:

//Header File Foo.h
    struct Foo; // Forward Declaration Only
    Foo*  createFoo( /* parameters */ );
    void  destroyFoo( Foo* obj );
    int Func( Foo* obj, int i ); // obj should take this pointer 
    float Func2( Foo* obj, float i, float j );

Implement it like this

#include "Foo.h"
extern "C" 
{
  Foo* createFoo( const char * s )
  {
    return reinterpret_cast<Foo*>( new Foo( s ) );
  }
  void destroyFoo( Foo* obj )
  {
    delete reinterpret_cast<Foo*>(obj );
  }
  int Func( Foo* obj, int i )
  {
    return reinterpret_cast<Foo*>(obj)->Func(i);
  }
}

Finally you can wrap your exported C function in a C# class so things get back to the traditional object oriented way.

Notice that I didn't even mention Inheritance or polymorphism.

like image 75
concept3d Avatar answered Mar 30 '23 00:03

concept3d


You cannot import native C++ classes directly to C#. They need to be wrapped one way or another. You can wrap them with C style non-member functions. You'll need to export functions that create and destroy the instances. All in all it's pretty horrid process.

The smart way to do this is to wrap compile the native C++ code into a mixed-mode C++/CLI assembly. You can then expose the functionality as a managed ref class. The interop then becomes trivial and you don't need to run the gauntlet of writing p/invoke declarations by hand.

like image 39
David Heffernan Avatar answered Mar 29 '23 22:03

David Heffernan