How to Dllexport a C++ Class for Use in a C# Application

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

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;
}
};

Is is possible to export functions from a C# DLL like in VS C++?

Unmanaged Exports =>
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

DLLExport => https://github.com/3F/DllExport

How does it work?


Create a new classlibrary or proceed with an existing one.
Then add the UnmanagedExports Nuget package.

This is pretty much all setup that is required.

Now you can write any kind of static method, decorate it with [DllExport] and use it from native code.

It works just like DllImport, so you can customize the marshalling of parameters/result with MarshalAsAttribute.

During compilation, my task will modify the IL to add the required exports...

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

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.

using a class defined in a c++ dll in c# code

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.

class Foo {
public:
int Bar();
};
extern "C" Foo* Foo_Create() { return new Foo(); }
extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; }

Now it's a matter of PInvoking these methods into your C# code

[DllImport("Foo.dll")]
public static extern IntPtr Foo_Create();

[DllImport("Foo.dll")]
public static extern int Foo_Bar(IntPtr value);

[DllImport("Foo.dll")]
public static extern void Foo_Delete(IntPtr value);

The downside is you'll have an awkward IntPtr to pass around but it's a somewhat simple matter to create a C# wrapper class around this pointer to create a more usable model.

Even if you don't own this code, you can create another DLL which wraps the original DLL and provides a small PInvoke layer.

Exporting functions from C++ dll to C# P/Invoke

Are you using a .def file in your dll project to export those functions? If so, remove it and try again. This is just a guess because it looks like your exports are not what they should be when you do an extern "C" declspec(dllexports).

I tried this out with a simple C++ dll using

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();

and a simple C# app using your PInvoke declarations and it worked fine.

When I did a dumpbin/exports on the dll I saw:

Dump of file PPPManager.dll

File Type: DLL

Section contains the following exports for PPPManager.dll

00000000 characteristics
499F6C2D time date stamp Fri Feb 20 20:51:25 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names

ordinal hint RVA name

1 0 000110CD Install = @ILT+200(_Install)
2 1 00011069 PPPConnect = @ILT+100(_PPPConnect)

Notice that the exported names are different in my case.

Import C++ Class Method from C#

Well there is a few ways, all with different merrits.

One of the more simple is to make a C-wrapper for your C++ class (i'm too lazy to put in the decorations, you should do that yourself).

class SomeClass {
public:
void M();
};

void* MakeSomeClass() {return new SomeClass();}
void DestroySomeClassHandle(void* handle) { delete (SomeClass*)handle;}
void M(void* handle) { ((SomeClass*)handle)->M();}

Then you import the C functions as you normally would.

The upside to this is you don't have to do anything you aren't currently familiar with. Many more things (Matlab, Python, ect) have things similar to PInvoke, so this makes your code much more cross-language usable.

The downside is this is super error prone, and you throw away alot of your type safety.

The better way (imho) is to make a C++/CLI wrapper for the class

public ref class ManageSomeClass
{
public:
ManageSomeClass() {myclass_ = new SomeClass();}
!ManageSomeClass() { if (myclass) {delete myclass; myclass_ = NULL;} }
~ManageSomeClass() { this->!ManageSomeClass(); }
void M() { myclass_->M();}
private:
SomeClass* myclass_;
};

I used SomeClass as a pointer to show the destructor-finalizer, but it doesn't need to be a pointer. It could be a full instance. The big thing is that this will be compiled into a .NET class (in a dll) and you can import it into your C# code. Then the call is:

//c# code
ManageSomeClass msc = new ManageSomeClass();
msc.M();

Upside is the flexibility to go from managed to unmanaged like that. The downside is that you are suddenly maintaining another interface. If you have inheritence/polymorphism, your wrappers have to mirror that structure. This is also a nightmare to maintain.

Edit: Another downside is you have to learn C++/CLI, which is (kindof) and extension of C++ and also (kindof) a completely different language.

The final way is through COM interfaces. http://msdn.microsoft.com/en-us/library/aa645736%28v=vs.71%29.aspx. You can use the same COM import calls you use in C++ in C# (with some minor differences) to instantiate and call COM classes. But you need to learn COM (which I've never done) and then implement your class in a COM complaint way. But then you have a COM interface, which can be imported all over Windows.

How do you limit what gets exported from a c# dll?

Mark the types/members that you want to be externally available as public, and the things you don't want to export as either internal, or (where available - members and nested types) private. If unspecified, top-level classes default to internal, and methods default to private.

How to export C++ class as a dll?

From MSDN

To export all of the public data members and member functions in a class, the keyword must appear to the left of the class name as follows:

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

Also, consider that there are more ways to do this, like .DEF-files.
Take your time to read through the explanations on the MSDN-site.



Related Topics



Leave a reply



Submit