Writing a C++ DLL, then wrapping it in C#
I am a bit co开发者_运维百科nfused 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 :-)
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).
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.
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.
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.
精彩评论