views:

468

answers:

4

Hello,

I am a bit confused about wrapping a c++ dll in c#. What kind of dll should i create? A normal dll or an mfc dll? Should i prefix every proto with "extern..." ? Should i write the functions in a def file?

My last effort was in vain, c# would crash with an error like "bad image format", which means that the dll format is not correct?

Any help would be much appreciated.

Thanks in advance :-)

+2  A: 

You could try creating a .NET dll using C++/CLI. The .NET-Dll is easy to use in C# and can access the c++-dll nativly. That's the way MOGRE creates the wrapper for OGRE.

I don't know for sure, but SWIG might help you with this task. I haven't worked with it but it is used a lot for creating wrappers.

Tobias Langner
+3  A: 

You can just create a normal kind of C++ dll, and interop with it from your C# code.

Here's a tutorial that you can use.

Ngu Soon Hui
+4  A: 

Are you using a 64-bit PC?

"Bad image format" will occur on an x64 system if you try to mix x64 code and x86 code. This will happen if you write C# code (targeted to "Any CPU", so it'll jit-compile to x64 code) that calls an unmanaged DLL (that will probably be x86 by default).

Two solutions to this are:

  • (Proper solution) Make sure the dll is compiled to target x64 so the whole program can run as a native 64-bit app, or
  • (Backwards compatibility solution) Force your whole application to run as an x86 app. In the C# project properties, change the Build "Any CPU" setting to "x86".

Otherwise, you should be able to create a normal COM dll (with or without MFC shouldn't matter) and then just wrap it in an RCW (Runtime callable wrapper).

Jason Williams
+1  A: 

Unless you really need it to be a COM/MFC dll, for example you need to plug it into an MFC application, then things might be clearer for you if you make it a straight C++ .dll.

In answer to your question regarding the extern keyword - I think this is only used in the calling application, when you are including a .lib file.

Here is a tutorial on creating straight C++ dll's.

Once you have your dll, the issue then becomes the fact that you're dealing with unmanaged code in your dll versus managed code in your C# application. In other words, because C++ knows nothing about the managed types used in C# and similarly, C# has no idea how to handle the memory for types used in the C++ dll, its then down to you to manage the memory in your dll. The C# garbage collector can only deal with memory in the C# application.

I think an answer could be to create a 'normal' dll in C++, then create a wrapper for it in C++/CLI that contains all the memory management - and the conversion from C++ unmanaged types to C# types and vice versa. You may need to use the marshal class to convert between managed types (C#) and unmanaged types (C++). And then, you import the C++/CLI wrapper rather than the C++ dll directly. Calling the functions then becomes trivial in your C# application, because the wrapper has done the "bridge work".

I've done something similar with a thirdparty C++ dll and I don't think this is as bad as it sounds.

Here is a tutorial on how to do this.

BeeBand