从本机 C++ 调用 C#,而不使用 /clr 或 COM?

Posted

技术标签:

【中文标题】从本机 C++ 调用 C#,而不使用 /clr 或 COM?【英文标题】:Calling C# from native C++, without /clr or COM? 【发布时间】:2009-08-22 00:33:06 【问题描述】:

以前有人问过这个问题,但我从未找到真正令人满意的解决方案 -

我有一个用 C# 编写的类库,我想从旧的本机 C++ 应用程序中调用它。主机应用程序是真正的原生应用程序,在 Windows 和 Linux 上编译,它是一个控制台应用程序。那么如何让它调用 C# 类库,假设在 Windows 上使用 Microsoft .NET,在 Linux 上使用 Mono。

我已经查看了 SWIG 并在 Windows 上使用 COM 接口进行包装,但是是否有一个公认的跨平台工作的标准解决方案?也就是说,它是通用的,适用于 Microsoft .NET 和 Mono,一次写入,随处使用。

解决方案应将完整的类接口从 C# 域公开到 C++ 域。

类似问题仅关注 Windows 解决方案,例如 -

Call C# methods from C++ without using COM

【问题讨论】:

你得问问那些单声道的人,他们是否以及如何导出它。 【参考方案1】:

如果您想跨平台,我建议您使用 100% Mono 方法。

Mono 有一个干净的Embedding API,可以在 Linux 和 Windows 上运行。

【讨论】:

很好的答案,在 Windows 上嵌入 Mono 并不是我真正想要的,而且看起来非常手动。您将不得不编写大量样板代码来向库公开完整的接口,它看起来既耗时又脆弱,这让我想起了 JNI。我想知道是否有某种自动化方式,比如 SWIG 或者只是公开一个 COM 接口。 COM 运行良好,但在 linux 上运行不佳。 SWIG 只适合另辟蹊径......对不起。【参考方案2】:

使用 .NET 5.0(.NET core 的后续版本),现在可以跨平台从 C++ 调用 C#,而无需使用 Mono。请参阅in this Github issue 解释的解决方案,使用 DNNE 生成共享库和 GCHandles 以访问 C# 对象。

通过这个,您可以获得一个可以在 C 或 C++ 中使用的共享库。请注意,这将提供一个类似 C 的 API(没有对象,就像在 C++ 中使用 extern C 时一样),将来可能会有像 SWIG 这样的 C++ 工具来克服这个限制。

【讨论】:

请内嵌代码。如果不行,请直接链接到代码sn-p,而不是包含多个cmets的github issue。 @Gili 这里是一个 sn-p 演示了可以使用此方法调用的 C# 接口:github.com/dotnet/docs/issues/18174#issuecomment-642124735 人们应该参考DNNE documentation 了解如何创建 DLL。这是一个非常新的功能(.NET 5.0 仍处于测试阶段),但由于在任何地方都没有提到它,所以我认为没有更多的内联内容是可以的。此外,尽管没有内联代码,但发现另一个答案很有帮助(+5)。

以上是关于从本机 C++ 调用 C#,而不使用 /clr 或 COM?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 库和 C++ (CLR) 之间传递对象

托管 c++ 库,它是如何工作的?

从 C++ 调用 C# dll

运行使用 /clr 构建的 DLL 的本机 C++ 应用程序时访问冲突

如何使用 pinvoke 将图像从 c 或 c++ 发送到 C#

从 C# 调用 C++ dll 方法/类