tags:

views:

3242

answers:

6

I have a dll that was written in c++, I need to use this dll in my c# code. After searching I found that using P/Invoke would give me access to the function I need, but these functions are defined with in a class and use non-static private member variables. So I need to be able to create an instance of this class to properly use the functions. How can I gain access to this class so that I can create an instance? I have been unable to find a way to do this.

I guess I should note that the c++ dll is not my code.

+8  A: 

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();
};
Foo* Foo_Create() { return new Foo(); }
int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
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")]
pulbic 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.

JaredPar
+2  A: 

You may need to write an intermediary DLL (in C++, perhaps) that handles this for you and exposes the interface you need. Your DLL would be in charge of loading the 3rd party DLL, creating an instance of this C++ object, and exposing its member functions as needed via whatever API you design. You would then use P/Invoke to get at your API and cleanly manipulate the object.

Note: For the API of your DLL, try keeping the data types limited to primitives (long, int, char*, etc.) to prevent module boundary issues.

Brian
+1  A: 

I agree with JaredPar. Creating instances of unmanaged classes in managed code should not be possible.

Another thing is - if you could recompile the DLL in managed C++ or make a COM component out of it, it would be much easier/

badbadboy
A: 

Here is a sample how to call C++ class method from VB - for C# you only have to rewrite the sample program in Step 4.

Dmitry Khalatov
A: 

The way I've done this is by creating a thin Managed C++ wrapper around my unmanaged C++ DLL. The managed wrapper contains "proxy" classes that wrap around the unmanaged code exposing the interface that's needed by the .NET application. This is a bit of double work but it allows quite seamless operation in normal environments. Things do get trickier with dependencies in some circumstances (such as ASP.NET) but you will probably not run into that.

MadKeithV
+1  A: 

myfile.i

%module learnaboutswig

class A

{

public:

void boringfunction(char *charstr);

};

download swig from swig.org

swig -c++ -csharp myfile.i

look at the output, see if it will work for you.

iterationx