具有托管子类的非托管基类

发布于 2024-08-03 19:20:00 字数 165 浏览 3 评论 0原文

是否有可能拥有:(

  1. 非托管)C++ 中的纯抽象类(基本上是一个接口)
  2. 在<插入您选择的 .net 语言>中拥有该类的托管实现
  3. 从(非托管)C++ 使用这些托管实现?

使用 SWIG 或某些 C++/CLI 胶水

Is it possible to have:

  1. A pure abstract class (basically an interface) in (unmanaged) C++
  2. Have managed implementations of this class in <insert .net language of your choice>
  3. Consume these managed implementations from (unmanaged) C++

Using SWIG or some C++/CLI glue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫南 2024-08-10 19:20:00

您通常可以编写自定义 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.

独木成林 2024-08-10 19:20:00

SWIG 是您要在此处使用的工具。具体来说,使用 SWIG 控制器。来自在线文档:

SWIG 控制器功能向生成的 C# 代理类添加了额外的代码,使这些类能够用于跨语言多态性。从本质上讲,它使非托管 C++ 代码能够回调虚拟方法的托管代码,以便 C# 类可以从包装的 C++ 类派生。

这很简单,尽管细节决定成败。对于对象的生命周期要非常小心——您正在处理两种不同的内存管理方法,如果您不小心,很容易最终得到无效的指针。但这完全是另一回事了;)

SWIG is the tool you want to use here. Specifically, use SWIG directors. From the online documentation:

The SWIG directors feature adds extra code to the generated C# proxy classes that enable these classes to be used in cross-language polymorphism. Essentially, it enables unmanaged C++ code to call back into managed code for virtual methods so that a C# class can derive from a wrapped C++ class.

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;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文