views:

672

answers:

5

I've got a native C++ DLL that I would like to have a C++/CLI wrapper layer for. From what I understood, if you simple added a C++/CLI class to the project, VS would compile as mixed mode, but I was apparently wrong as VS doesn't seem to be even touching the managed code.

So, given a pre-existing native code-base what exactly, step-by-step, do you need to do to create a mixed mode DLL, so that I can can link into that code from any .NET language?

*I need to do this because my native code uses C++ classes that I cannot P/Invoke into.

+2  A: 

Begin a new C++/CLI project and then move your native classes to it.

danbystrom
+1  A: 

Well, no, it doesn't get to be mix-mode until you tell the C++/CLI compiler that your legacy DLL was written in unmanaged code. Which should have been noticeable, you should have gotten linker errors from the unmanaged DLL exports. You need to use #pragma managed:

#pragma managed(push, off)
#include "oldskool.h"
#pragma comment(lib, "oldskool.lib")
#pragma managed(pop)

public ref class Wrapper {
private:
  COldSkool* pUnmanaged;
public:
  Wrapper() { pUnmanaged = new COldSkool; }
  ~Wrapper() { delete pUnmanaged; pUnmanaged = 0; }
  !Wrapper() { delete pUnmanaged; }
  void sampleMethod() { pUnmanaged->sampleMethod(); }
};
Hans Passant
I assume this is for if you were creating a new DLL and linking to the completely native DLL?
Adam Haile
@Adam: that's correct.
Hans Passant
Whether that pulls in a native DLL depends on whether oldskool.lib is an import library or a static library.
Ben Voigt
A: 

If you has a source code of the DLL with native C++, you can use managed C++ in the mixed mode. Microsoft has for some time a reference project of migration of some well known DirectX game to .NET. One used managed C++ in the mixed mode. A part of code was rewritten as managed code. A part was shortly changed to be compiled as C++ in the mixed mode and a part was compiled as assembly code (because of performance reason), but used also directly inside of managed code as unsafe code. Such kind of migration follow as a result to really very good performance in the end application. In this way you don't spend time for marshaling between native and managed code. Marshaling between safe and unsafe managed code is much quickly. Probably you should also choose this way?

Another way calling native code from DLL inside of manged .NET code is well known. Every C++ function has undecorated names (use http://www.dependencywalker.com/ to see there). If your C++ DLL export classes and not C-like functions, this DLL is bad designed. Good designed DLL either exports C-like functions or export COM-interfaces. If you have such "bad" DLL and don't want spend time to write a COM, you can easy write one more DLL which will be play a stub role. This DLL imports all C++ classes (see http://msdn.microsoft.com/en-us/library/81h27t8c.aspx, http://stackoverflow.com/questions/27998/exporting-a-c-class-from-a-dll and http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx for example) from "bad" DLL and export C-like function. This way is also OK.

Oleg
A: 

The C++ project file needs the /clr option. This can be set for the whole project on the general tab, I believe, or set on individual files.

Once the clr option is specified Visual Studio will build that class using C++/CLI.

MrSlippers
tried that originally and it really didn't like that...
Adam Haile
What didn't it like?
MrSlippers
A: 

A good option to prevent /clr from affecting your existing code is to compile all the existing code into a native static library and then include that static library at the link step of your C++/CLI dll.

Ben Voigt