Exporting a C++ Class from a Dll

How to export a C++ class from a dll?

A common approach is to have a single macro (let's call it EXPORT) which either expands to dllimport or dllexport depending on whether some sort of "building the DLL right now" define is set, like this:

#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. Clients who link against your DLL (and hence include this header file) don't need to do anything at all. By not defining MAKEDLL, they will automatically import all the code.

The advantage of this approach is that the burden of getting the macros right is moved from the many (the clients) to just the author of the DLL.

The disadvantage of this is that when using the code above as it is, it's no longer possible to just compile the code directly into some client module since it's not possible to define the EXPORT macro to nothing. To achieve that, you'd need to have another check which, if true, defines EXPORT to nothing.

On a slightly different topic: in many cases, it's not possible (or desired!) to export a complete class like that. Instead, you may want to just export the symbols you need. For instance, in your case, you may want to just export the two public methods. That way, all the private/protected members won't be exported:

class xyz
{
public:
EXPORT void printing();
EXPORT void printing(int a);
};

Exporting a C++ class from a DLL

What about late-binding? As in loading
it with LoadLibrary() and
GetProcAddress() ? I'm used being able
to load the library at run time and it
would be great if you could do that
here.

So there are two ways to load the DLL. The first is to reference one or more symbols from the DLL (your classname, for example), supply an appropriate import .LIB and let the linker figure everything out.

The second is to explicitly load the DLL via LoadLibrary.

Either approach works fine for C-level function exports. You can either let the linker handle it or call GetProcAddress as you noted.

But when it comes to exported classes, typically only the first approach is used, i.e., implicitly link to the DLL. In this case the DLL is loaded at application start time, and the application fails to load if the DLL can't be found.

If you want to link to a class defined in a DLL, and you want that DLL to be loaded dynamically, sometime after program initiation, you have two options:

  1. Create objects of the class using a special factory function, which internally will have to use (a tiny bit of) assembler to "hook up" newly created objects to their appropriate offsets. This has to be done at run-time AFTER the DLL has been loaded, obviously. A good explanation of this approach can be found here.

  2. Use a delay-load DLL.

All things considered... probably better to just go with implicit linking, in which case you definitely want to use the preprocessor technique shown above. In fact, if you create a new DLL in Visual Studio and choose the "export symbols" option these macros will be created for you.

Good luck...

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.

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 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 there a way to ⎕NA import a dll exported C++ class in dyalog APL?

Have you read "Name Association" description?
http://help.dyalog.com/latest/Content/Language/System%20Functions/na.htm
I guess it could help. There are some examples in the end of the article.

Importing a class from a c# dll into a c++ app

I normally do this kind of stuff by creating a static C++ CLR Wrapper Lib.

These are the steps I'm normally using (although I don't use it very often):

Here minimal example with using Visual Studio:

1. Create managed C# .NET library Project

Let name it HelloLibManaged
with one file Hello.cs and following content:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloLibManaged
{
public class Hello
{
public void Print()
{
System.Console.WriteLine("Hello from Managed Lib");
}
}
}

Build this lib with x86 or x64 , just dont Any CPU

2. Create a new C++ CLR static lib project within same solution.
Let's name it HelloLibCpp

  • Add a reference to HelloLibManaged project via Project->Add Reference

  • Remove automatic created existing .h/.cpp files from Project, and create these 2 files:

HelloUnmanaged.h

#pragma once

namespace hello_managed {

class Hello
{
public:
void Print();
};
}

and

HelloUnmanaged.cpp:

#include "HelloUnmanaged.h"

namespace hello_managed
{

void Hello::Print()
{
HelloLibManaged::Hello^ hello = gcnew HelloLibManaged::Hello();
hello->Print();
}

}

Und Project Properties -> General specify static lib.
In the Build settings specify x86 / x64 - use the same build type as building Managed lib from Step 1.

Now you can build the dll and use it in your other unmanaged C++ projects.

For more advanced stuff, like return types and methods with parameters you have to do Type-Marshalling between managed/unmanaged code. There are many resources online with more information about Type-Conversion between managed/unmanaged code. Keyword: Marshaling.

make c++ class in a native dll to use in C#

Having done this a bunch of times, the easiest way to do this is to write a C++/CLI wrapper to your existing classes. The reason being that P/Invoke works best on calls that are strictly C functions and not methods in a C++ class. In your example, how would you call operator new for the class that you specify?

If you can write this as a C++/CLI dll, then what you get is something that looks like this:

public ref class CliHuman {
public:
CliHuman() : _human(new Human()) { }
~CliHuman() { delete _human; }
protected:
!CliHuman() { delete _human; }
public:
void DoPee() { _human->Do_Pee(); }
private:
Human *_human;
};

Now, you might not have the freedom to do this. In this case, your best bet is to think about what it would take to expose a C API of your C++ object. For example:

extern "C" {

void *HumanCreate() { return (void *)new Human(); }
void HumanDestroy(void *p) { Human *h = (Human *)h; delete h; }
void HumanDoPee(void *p) { Human *h = (Human *)h; h->Pee(); }

};

You can P/Invoke into these wrappers very easily.

From an engineering standpoint, you would never want to do this ever since calling .NET code could pass in any arbitrary IntPtr. In my code, I like to do something like this:

#define kHumanMagic 0xbeefbeef;

typedef struct {
int magic;
Human *human;
} t_human;

static void *AllocateHuman()
{
t_human *h = (t_human *)malloc(sizeof(t_human));
if (!h) return 0;
h->magic = kHumanMagic;
h->human = new Human();
return h;
}

static void FreeHuman(void *p) /* p has been verified */
{
if (!p) return;
t_human *h = (t_human)p;
delete h->human;
h->human = 0;
h->magic = 0;
free(h);
}

static Human *HumanFromPtr(void *p)
{
if (!p) return 0;
t_human *h = (t_human *)p;
if (h->magic != kHumanMagic) return 0;
return h->human;
}
void *HumanCreate() { return AllocateHuman(); }
void HumanDestroy(void *p)
{
Human *h = HumanFromPtr(p);
if (h) {
FreeHuman(p);
}
else { /* error handling */ }
}
void HumanPee(void *p)
{
Human *h = HumanFromPtr(p);
if (h) h->Do_Pee();
else { /* error handling */ }
}

What you can see that I've done is create a light wrapper on top of the class that lets me verify that what comes in is more likely to be a correct pointer to what we want. The safety is likely not for your clients but for you - if you have to wrap a ton of classes, this will be more likely to catch errors in your code where you use one wrapper in place of another.

In my code base, we have found it especially useful to have a structure where we build a static library with the low-level code and the C-ish API on top of it then link that into a C++/CLI project that calls it (although I suppose to could P/Invoke into it from C# as well) instead of having the C++/CLI directly wrap the C++. The reason is that (to our surprise), all the low-level code which was using STL, was having the STL implementations done in CLI rather than in x86 or x64. This meant that supposedly low-level code that was iterating over STL collections would do something like 4n CLI transitions. By isolating the code, we worked around that quite well.

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