Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C++ Class DLL in C# Application

I have an unmanaged C++ DLL which merely exports a single class (not COM...it's just a simple C++ class) as its interface. I want to use this class in C# but am told that it cannot merely be imported into C#.

What is the right way to use this class in my C# application?

like image 854
cjserio Avatar asked Feb 20 '09 13:02

cjserio


People also ask

Can a DLL have classes?

You can declare C++ classes with the dllimport or dllexport attribute. These forms imply that the entire class is imported or exported. Classes exported this way are called exportable classes. #define DllExport __declspec( dllexport ) class DllExport C { int i; virtual int func( void ) { return 1; } };

Can I use a C++ DLL in C#?

Yes, it will work.

How to use a C++ class in C#?

There is no way to directly use a C++ class in C# code. You can use PInvoke in an indirect fashion to access your type. The basic pattern is that for every member function in class Foo, create an associated non-member function which calls into the member function.

How to export class in DLL?

#ifdef MAKEDLL # define EXPORT __declspec(dllexport) #else # define EXPORT __declspec(dllimport) #endif class EXPORT xyz { // ... }; The idea is that when building your DLL, you add MAKEDLL to the preprocessor definitions. That way, all the code will be exported.


5 Answers

Simple way assuming class Foo:

  1. Create a C++/CLI project, call this FooWrapper.
  2. Make FooWrapper depend on the unmanaged dll (however you normally would).
  3. Create a managed class ManagedFoo which contains a single private instance field of type Foo*.
  4. provide public wrapping functions in ManagedFoo which forward on to the underlying instance field.
  5. Optionally (though recommended):
    • convert parameters from .net idioms (strings and the like) to C++ idioms (std::string or char*)
    • catch unmanaged exceptions and throw managed ones instead

Then you make your c# code depend on the FooWrapper project/dll and ensure that the unmanaged dll is properly deployed with it, how that is done depends on the unmanaged dll but in the same directory is normally sufficient.

If the functions do not rely on instances of the class then even simpler is P/Invoke

like image 94
ShuggyCoUk Avatar answered Oct 05 '22 06:10

ShuggyCoUk


This answer might be overkill for a single class library, but SWIG is a good solution for "wrapping" C/C++ classes for use from other languages. It works well with C#.

See http://www.swig.org/.

like image 25
Stewart Avatar answered Oct 05 '22 07:10

Stewart


DllImport is your best bet. There is a bit of data type massaging, especially if you are passing structs, but you can do almost anything with it.

like image 23
Steve Avatar answered Oct 05 '22 07:10

Steve


You need an proxy (GoF pattern) intermediary to bridge the managed/unmanaged boundary.

Two options:

  • A C++/CLI wrapper
  • A COM wrapper.

The former will be more direct, and latter has two steps pure C++ -> COM -> .NET.

like image 42
Richard Avatar answered Oct 05 '22 06:10

Richard


Sometimes, it is easier to provide your own C interface. SWIG is non-trivial to setup. I have use managed C++ and C++/CLI and they are fine. The easiest was just doing a C wrapper (and can be used by about any other language since most have a way to call a C function).

like image 29
chrish Avatar answered Oct 05 '22 06:10

chrish