从 C++ 调用 C# 代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/778590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:47:16  来源:igfitidea点击:

Calling C# code from C++

c#c++-cliinterop

提问by Gili

I need to be able to invoke arbitrary C# functions from C++. http://www.infoq.com/articles/in-process-java-net-integrationsuggests using ICLRRuntimeHost::ExecuteInDefaultAppDomain() but this only allows me to invoke methods having this format: int method(string arg)

我需要能够从 C++ 调用任意 C# 函数。http://www.infoq.com/articles/in-process-java-net-integration建议使用 ICLRRuntimeHost::ExecuteInDefaultAppDomain() 但这仅允许我调用具有以下格式的方法:int method(string arg)

What is the best way to invoke arbitrary C# functions?

调用任意 C# 函数的最佳方法是什么?

采纳答案by Dаn

Compile your C++ code with the /clrflag. With that, you can call into any .NET code with relative ease.

使用/clr标志编译您的 C++ 代码。有了它,您可以相对轻松地调用任何 .NET 代码。

For example:

例如:

#include <tchar.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    System::DateTime now = System::DateTime::Now;
    printf("%d:%d:%d\n", now.Hour, now.Minute, now.Second);

    return 0;
}

Does this count as "C++"? Well, it's obviously not Standard C++...

这算作“C++”吗?嗯,这显然不是标准 C++...

回答by laktak

The easiest way is to use COM interop.

最简单的方法是使用 COM 互操作。

回答by Filip Fr?cz

If you don't care if your C++ program (or a portion of it) gets compiled with the /clr, you can use C++/CLI to simply call any .NET code (as long as you add a reference to it). Try out this article.

如果您不关心您的 C++ 程序(或其中的一部分)是否使用 /clr 编译,您可以使用 C++/CLI 来简单地调用任何 .NET 代码(只要您添加对它的引用)。 试试这篇文章

EDIT: Here is a nice tutorial

编辑:这是一个很好的教程

The other route is to make your C# code be exposed as COM.

另一种方法是使您的 C# 代码公开为 COM。

回答by Dan Vinton

You could use a COM callable wrapperaround your C# code compiled into a DLL.

您可以在编译成 DLL 的 C# 代码周围使用COM 可调用包装器

回答by David Robbins

As an alternate approach, you could use Luato instantiate the CLR objects, execute, and return the results.

作为替代方法,您可以使用Lua来实例化 CLR 对象、执行并返回结果。

回答by cdiggins

There are several ways for a C++ application to invoke functions in a C# DLL.

C++ 应用程序可以通过多种方式调用 C# DLL 中的函数。

  1. Using C++/CLI as an intermediate DLL
  2. Reverse P/Invoke
  3. Using COM
  4. Using CLR Hosting (ICLRRuntimeHost::ExecuteInDefaultAppDomain())
  5. Interprocess communication (IPC)
  6. Edit: Host a HTTP server and invoke via HTTP verbs (e.g. a REST style API)
  1. 使用 C++/CLI 作为中间 DLL
  2. 反向 P/调用
  3. 使用 COM
  4. 使用 CLR 托管 ( ICLRRuntimeHost::ExecuteInDefaultAppDomain())
  5. 进程间通信 (IPC)
  6. 编辑:托管 HTTP 服务器并通过 HTTP 动词调用(例如 REST 风格的 API)

回答by Contango

See DllExport.

请参阅DllExport

IOW:The exact opposite of how DllImportworks.

IOW:DllImport工作方式完全相反。

https://github.com/3F/DllExport

https://github.com/3F/DllExport

It has support for Windows, with cross-platform support in the works.

它支持 Windows,跨平台支持正在开发中。

C# code (which we call from C++):

C# 代码(我们从 C++ 调用):

[DllExport]
public static int _add(int a, int b)
{
    return a + b;
}

[DllExport]
public static bool saySomething()
{
    DialogResult dlgres = MessageBox.Show(
        "Hello from managed environment !",
        ".NET clr",
        MessageBoxButtons.OKCancel
    );

    return dlgres == DialogResult.OK;
}

C++ code (which calls previous C# code):

C++ 代码(调用以前的 C# 代码):

typedef int(__cdecl *_add)(int a, int b);
typedef bool(__cdecl *saySomething)();

auto pAdd = (_add)GetProcAddress(lib, "_add");
int c = pAdd(5, 7);

auto pSaySomething = (saySomething)GetProcAddress(lib, "saySomething");
bool dlgres = pSaySomething();

And a YouTube video with a demo at Managed & Unmanaged; PInvoke; [ Conari vs DllExport]. To be honest, the documentation is a cut below perfect, but don't let that put you off: the YouTube videos are excellent.

以及在托管和非托管上带有演示的 YouTube 视频调用;[Conari 与 DllExport]。老实说,文档是完美的,但不要让这让你失望:YouTube 视频非常好。

This project is inspired by another project from Robert Gieseckewhich has 220,000 downloads on NuGet.

该项目的灵感来自 Robert Giesecke的另一个项目,该项目在 NuGet 上220,000 次下载

Fun fact: some Python libraries have used this to implement functionality in a mix of C++ and C#.

有趣的事实:一些 Python 库使用它来实现 C++ 和 C# 混合的功能。

And finally, thank you Robert Giesecke and Denis Kuzmin, brilliant, brilliant work!

最后,感谢 Robert Giesecke 和 Denis Kuzmin,出色的工作!

回答by Contango

From Microsoft: Write a custom .NET Core host to control the .NET runtime from your native code.

来自 Microsoft:编写自定义 .NET Core 主机以从您的本机代码控制 .NET 运行时

IOW:Call C# from from C++ on both Windows and Linux.

IOW:在 Windows 和 Linux 上从 C++ 调用 C#。

There is sample code on GitHub.

GitHub 上示例代码

This sample code is cross platform, it allows C# code in .NET Core to be called from any C++ application on both Linux and Windows.

此示例代码是跨平台的,它允许从 Linux 和 Windows 上的任何 C++ 应用程序调用 .NET Core 中的 C# 代码。

In all honesty, this solution seems to be quite complicated compared to the other DllExportanswer. The C++ code is doing a lot of heavy lifting to scan for resouces and entry points, etc. One argument for this answer could be that it is cross-platform. However, the other DllExportanswer is also cross-platform as well, and a lot simpler to use.

老实说,与其他DllExport答案相比,这个解决方案似乎相当复杂。C++ 代码做了很多繁重的工作来扫描资源和入口点等。这个答案的一个论点可能是它是跨平台的。但是,另一个DllExport答案也是跨平台的,而且使用起来要简单得多。