编组包装 c++ 时 Intptr 是否足够?接口(都是抽象的)通过传递接口句柄来工作?
我试图包装一个由几个抽象结构(带有所有纯虚拟方法)和一个小型工厂命名空间组成的非托管 C++ 接口,该命名空间将句柄(shared_ptrs)返回到这些结构。
看来,正因为如此,我可能能够仅仅通过将指针编组为 System.IntPtr 类型(尽管它们是 boost::shared_ptr 类型,这样可以吗还是我需要额外的处理?)并传递它们围绕简单的托管包装器,然后返回到本机代码,而无需担心它们指向什么。这是在正确的轨道上吗?
我将不胜感激任何有关 STL 类型或共享指针类型的 pinvoke 数据编组的帮助或参考(我在 MSDN 和其他网站上关于字符串和基元结构的信息很少。)
谢谢,
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,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议定义一个供 .NET 层使用的 C API。使用
void *
或const void *
作为结构的“句柄”类型,并为每个结构定义一个extern "C"
函数方法(包括工厂方法和析构函数)。您无法直接封送shared_ptr
参数,因此需要使用void *
句柄。在.NET层中,首先定义一个从
SafeHandle
派生的类型,其唯一目的是正确处理句柄(即调用代表对象析构函数的C API)。接下来,定义一个代表实际对象的包装类型,并具有代表该对象的成员函数的每个 C API 函数的方法。最后,定义一个包装 C API 工厂方法的工厂类型。虽然工作量很大,但这是正确的方法。
I recommend defining a C API to be consumed by the .NET layer. Use
void *
orconst void *
for the "handle" types to your structures, and define anextern "C"
function for each of the methods (including factory methods and the destructor). You can't marshal ashared_ptr<T>
argument directly, so you need to use thevoid *
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.
使用 COM,您只能编组/取消编组 COM 数据类型 ->您的界面应该是 COM 可转换的(有关构建 COM 的示例,请参阅此 C++ 中的对象)。
这并不意味着在接口的实现中你不能使用 stl 或 boost 类型,只是你的接口定义应该只包含 COM 可转换类型。有关 C++ 数据列表,请参阅此类型及其 COM 等效项。
如果您将使用 COM 对象,则不需要从 .net 中 PInvoke,因为您可以直接从 Visual Studio 中导入 .net 中的 COM 对象(添加引用 -> COM)。
如果直接调用非托管代码,则需要使用 PInvoke。有关 PInvoke 的入门信息,请参阅此。有关调用非托管代码的讨论,请参阅此问题使用 STL 容器。
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.