views:

3392

answers:

5

I have a C++ class I'd like to access from a C# application. I'll need to access the constructor and a single member function. Currently the app accepts data in the form of stl::vectors but I can do some conversion if that's not likely to work?

I've found a few articles online which describe how to call C++ DLLs and some others which describe how to make .dll projects for other purposes. I'm struggling to find a guide to creating them in Visual Studio 2008 for use in a C# app though (there seem to be a few for VS 6.0 but the majority of the options they specify don't seem to appear in the 2008 version).

If anyone has a step-by-step guide or a fairly basic example to get going from, I'd be very grateful.

+1  A: 

Do you have an existing C++ exe that you want to re-build as a dll? Or is all you have the C++ class?
If all you have is the C++ class, you might think about building a .Net dll. While you couldn't pass stl types from C# to C++, I am pretty sure you can pass managed .Net types.
If you must use the stl types in the class, you could convert the data in the C++ class, or the calling app.

Number8
I have a .exe but it's just a test harness. It's the class I want access to. I can't avoid the use of stl types internally but as you suggest, I can always convert from an array or whatever it is C# passes in. Any ideas what options you need to pick in VS?
Jon Cage
A: 

Use of unmanaged C++ Dlls can be very tedious in C#.

An "easier" route is to place it in a COM wrapper.

ChrisBD
Do you have any examples of either route to support what you're saying? As I said in the question, I was hoping for a simple example...
Jon Cage
+4  A: 

If such DLL is unmanaged. You will have to use P/invoke. A p/invoke function definition looks like this:

[DllImport("Library_Name.dll", EntryPoint = "function")]
public static extern void function();

If, on the other hand, is a managed (C++/CLI) DLL (or assembly). You can access it by adding a reference to it on your .NET project.

EDIT: I think I didn't answer your question at all. But to create a managed C++ DLL to be accessed from .NET, create a new project an choose: Visual C++/CLR/Class Library. And then, just add its output DLL to your C# project.

That'd do it. :)

Anzurio
A: 

I've found a tutorial which works. A quick note though, you have to be careful to copy the .dll into the same directory as the executable. I messed around with trying to tell the executable where the DLL was but gave up in the end.

Jon Cage
+1  A: 

The easiest way to interoperate between C++ and C# is by using managed C++, or C++/CLI as it is called. In VisualStudio, create a new C++ project of type "CLR Class Library". There is some new syntax for the parts that you want to make available to C#, but you can use regular C++ as usual.

In this example, I'm using std::vector<int> just to show that you can use standard types - however, in an actual application, I'd prefer to use the .NET types where possible (in this case a System::Collections::Generic::List<int>).

#pragma unmanaged
#include <vector>
#pragma managed

public ref class CppClass
{
public:
   CppClass() : vectorOfInts_(new std::vector<int>)
   {}

   // This is a finalizer, run when GC collects the managed object
   !CppClass()
   { delete vectorOfInts_; }

   void Add(int n)
   { vectorOfInts_->push_back(n); }

private:
    std::vector<int>* vectorOfInts_;
};

EDIT: Changed the class to hold the vector by pointer instead of by value.

Bojan Resnik
+1 > Nice example and something I can probably work from to convert what I have over - excellent stuff!
Jon Cage
..except when I try and compile I get [error C4368: cannot define 'vectorOfDoubles_' as a member of managed 'ManagedDLL::CppClass': mixed types are not supported] ?
Jon Cage
Ah, yes - forgot about that - managed types cannot contain unmanaged types by value. Holding a pointer to the vector should work just fine.
Bojan Resnik