I am trying to wrap an unmanaged c++ interface composed of several abstract structs (with all pure virtual methods) and a small factory namespace which returns handles (shared_ptrs) to these structs.
It seems that, because of this, I might be able to get away with merely marshalling pointers through as System.IntPtr types (although them being of type boost::shared_ptr, would that be ok or do i need开发者_高级运维 additional handling?) and passing them around to simple managed wrappers and then back into the native code without the need to every worry what they point to. Is this on the right track?
I would appreciate any help or references to data marshalling with pinvoke for STL types or shared_ptr types (all i can find is very little on MSDN and other sites on strings and structs of primitives.)
Thank you,
I recommend defining a C API to be consumed by the .NET layer. Use void *
or const void *
for the "handle" types to your structures, and define an extern "C"
function for each of the methods (including factory methods and the destructor). You can't marshal a shared_ptr<T>
argument directly, so you need to use the void *
handles.
In the .NET layer, first define a type derived from SafeHandle
whose sole purpose is to dispose the handle correctly (i.e., call the C API representing the object destructor). Next, define a wrapper type that represents the actual object, and has methods for each of the C API functions that represent member functions of the object. Finally, define a factory type that wraps the C API factory methods.
It's a lot of work, but this is the correct way to do it.
With COM you can only marshal/unmarshal COM data types -> you interface should be COM convertible (see this for an example of building a COM object in C++).
This does not mean that in the implementation of the interface you cannot use stl or boost types, it's just that your interface definition should only consist of COM convertible types. See this for a list of C++ data types and their COM equivalent.
If you will be using a COM object you will not need to PInvoke from .net, as you can directly import a COM object in .net from Visual Studio (Add reference-> COM).
You need to use PInvoke if you are doing direct calls to unmanaged code. See this for a starter on PInvoke. See this question for a discussion about calling unmanaged code that uses STL containers.
精彩评论