C++/CLI + Boost + Mono
General: I have a standa开发者_StackOverflow中文版rds compliant C++ API that uses Boost libraries that I would like to support as a native, statically linkable library on Windows, OS X, and Linux, and that I'd like to wrap for .NET on Windows and Mono on OS X and Linux.
Specifics: Currently I have it compiling natively for all platforms - this followed from using standard C++ and Boost. I also got it to compile and run for C++/CLI on Windows, but I was forced to use the Boost .DLLs. The next step I'm not sure where to begin with as I've never tried to use shared libraries on *nix systems. I know Boost provides shared libraries on Linux (and I'll presume the same is true on OS X), but will these just work auto-magically with my Visual Studios compiled C++/CLI executable, or do I need to do some work? There's no C++/CLI compiler for MonoDevelop, but supposedly Visual Studios compiled CLI will work just fine... it's the dynamically linked libraries that are confusing me.
C++/CLI assemblies will only load on Mono if they are compiled with /clr:pure
. A mixed mode C++/CLI assembly (which is any assembly using native code, ie: boost) will not run on non-Windows platforms.
Your best option is to provide a C API, and use P/Invoke to call into the native code. This is portable across platforms, provided you include the same C API on both platforms.
I am sure that you have found another solution by now but I am sure this question is still showing up in searches.
Mono has recently made some pretty big strides with C++ interoperability in CXXI.
From this posting, the short story is that the new CXXI technology allows C#/.NET developers to:
- Easily consume existing C++ classes from C# or any other .NET language
- Instantiate C++ objects from C#
- Invoke C++ methods in C++ classes from C# code
- Invoke C++ inline methods from C# code (provided your library is compiled with -fkeep-inline-functions or that you provide a surrogate library)
- Subclass C++ classes from C#
- Override C++ methods with C# methods
- Expose instances of C++ classes or mixed C++/C# classes to both C# code and C++ as if they were native code.
CXXI is the result of two summers of work from Google's Summer of Code towards improving the interoperability of Mono with the C++ language.
You cannot really do this in C++/CLI, because C++/CLI is not C++. As Reed says, you'd need to compile using /clr:pure
, which would force you to remove replace every single class with a CLR class, and which would essentially defeat the point of attempting to compile there in the first place.
Why are you trying to do this?
Keep in mind that .net adheres to "Fusion" as the model for locating libraries (which, in .net, are essentially all dynamically linked). On the Windows platform, native code does not follow the fusion load model. Check the LoadLibraryEx documentation, reading from where it says:
The LoadLibraryEx function performs a standard search for modules if the file name is specified without a path and the base file name does not match the base file name of a loaded module, or there is a path specified but LOAD_WITH_ALTERED_SEARCH_PATH is not used.
...and the following paragraphs. The way I have built the C# to C++/CLI, is to have my C# loader check whether it is currently being JITted as x86 or x64, and then I explicitly load the C++/CLI assembly matching that architecture. If you don't do that, then you cannot compile as "AnyCPU" on the C# side.
How this plays out outside of Windows I don't know...
精彩评论