具有托管子类的非托管基类
是否有可能拥有:(
- 非托管)C++ 中的纯抽象类(基本上是一个接口)
- 在<插入您选择的 .net 语言>中拥有该类的托管实现
- 从(非托管)C++ 使用这些托管实现?
使用 SWIG 或某些 C++/CLI 胶水
Is it possible to have:
- A pure abstract class (basically an interface) in (unmanaged) C++
- Have managed implementations of this class in <insert .net language of your choice>
- Consume these managed implementations from (unmanaged) C++
Using SWIG or some C++/CLI glue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您通常可以编写自定义 C++/CLI 粘合来将托管对象包装在非托管包装器中或将非托管对象包装在托管包装器中。如果您不想采用这种方法,您还可以利用 COM 和“COM/.NET 互操作”。换句话说,您可以在 COM .idl 文件中声明您的接口;完成此操作后,您应该能够在非托管和托管代码(C++、C++/CLI、C# 等)中使用(并实现)该接口。
在 C++(非托管或其他)中,您可以#import idl 或#include 您选择的编译器通过 midl.exe“编译”idl 后生成的头文件。对于 C#,您可以在 C++/CLI 中编写一些托管 API 来包装 COM 接口,也可以使用 tlbimp.exe 从 midl 生成的 COM 类型库 (.tlb) 自动生成托管程序集。此“互操作程序集”可以由任何常规的旧托管程序集直接引用。
(如果您不熟悉 COM 或 COM/.NET 互操作,这可能看起来有点神秘或神奇;有关如何向 .NET 公开 COM 组件的更多信息,这里有 MSDN 上的一些背景材料供您开始。)
成功公开 COM 组件后(s) 对于 .NET,在 .NET 中实现导出的 COM 接口之一应该像在 C# 或 C++/CLI 中定义一个从相关接口继承的新类一样简单。
至于要求#3……你如何解决它实际上取决于你想要解决的更广泛的问题。一旦您以某种方式将对托管对象(实现 COM 接口)的引用传递给本机代码,该代码实际上就可以像使用本机 COM 对象一样使用该对象;在大多数情况下,它可以完全不知道使用哪种语言来实现所需的 COM 接口。如果您提供有关问题背景的其他详细信息,我们也许能够提供有关如何实现此目标的其他指导。
You can mostly always write custom C++/CLI glue to wrap managed objects in unmanaged wrappers or unmanaged objects in managed wrappers. If you don't want to go with this approach, you can also leverage COM and "COM/.NET interop". In other words, you can declare your interface in a COM .idl file; once you've done this, you should be able to both consume (and implement) the interface in both unmanaged and managed code (C++, C++/CLI, C#, etc.).
In C++ (unmanaged or otherwise), you can #import the idl or else #include the header file(s) that your compiler of choice generates after "compiling" the idl through midl.exe. For C#, you can either write some managed APIs in C++/CLI to wrap the COM interfaces or you can use tlbimp.exe to auto-magically generate a managed assembly from the COM type library (.tlb) that midl generates. This "interop assembly" can be directly referenced by any regular old managed assembly.
(This might all seem a bit cryptic or magical if you're not familiar with COM or COM/.NET interop; for more information on how to expose COM components to .NET, here's some background material on MSDN to start you off.)
Once you've successfully exposed the COM component(s) in question to .NET, implementing one of the exported COM interfaces in .NET should be as simple as defining a new class in C# or C++/CLI that inherits from the interface in question.
As for requirement #3... how you go about it really depends on the broader problem you're trying to solve. Once you somehow pass a reference to the managed object (which implements the COM interface) to native code, that code can really just use the object as if it's a native COM object; it can--for the most part--remain blissfully unaware of which language was used to implement the required COM interfaces. If you provide additional details about the context of your problem, we might be able to provide additional pointers on how to make this happen.
SWIG 是您要在此处使用的工具。具体来说,使用 SWIG 控制器。来自在线文档:
这很简单,尽管细节决定成败。对于对象的生命周期要非常小心——您正在处理两种不同的内存管理方法,如果您不小心,很容易最终得到无效的指针。但这完全是另一回事了;)
SWIG is the tool you want to use here. Specifically, use SWIG directors. From the online documentation:
It's pretty simple, although the devil's in the details. Be very careful about object lifetime - you are dealing with two different memory management approaches, and if you're not careful it's easy to end up with invalid pointers. But that's a whole other story;)