从C++调用C#代码

Gil*_*ili 41 c# interop c++-cli

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

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

cdi*_*ins 48

C++应用程序有几种方法可以调用C#DLL中的函数.

  1. 使用C++/CLI作为中间DLL
  2. 反向P/Invoke
  3. 使用COM
  4. 使用CLR主机(ICLRRuntimeHost::ExecuteInDefaultAppDomain())
  5. 进程间通信(IPC)
  6. 编辑:托管HTTP服务器并通过HTTP谓词调用(例如REST样式API)

  • 这5种方法中的哪一种更可取,为什么?这将是有效的 (2认同)
  • 如果您正在寻找跨平台解决方案(因此 COM 或 C++ \clr 是不可能的),并且可以容忍平面 API(没有 OOP 语法,à la C API),[有](https://github.com/github.com/github.io/common/clr)。 com/dotnet/docs/issues/18174)(将是).NET 5 中的解决方案:使用此解决方案,您可以从 C# 代码创建一个 DLL,该 DLL 可以在 Linux 上从 C 或 C++ 使用(允许处理 C# 对象,就像您一样)可以在 C++ 代码的 C API 中执行)。 (2认同)

Ðаn*_*Ðаn 24

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

例如:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这算是"C++"吗?好吧,它显然不是标准C++ ......

  • 然后它不再是C++调用C#,它是C++/CLI调用C# - 你已经回避了这个问题.C++与C++/CLI是一个非常重要的区别,不应该被掩盖. (64认同)
  • "这算是C++吗?嗯,显然不是标准C++"......重点是普通的C/C++代码应该能够调用C#调用C#.看看这是如何工作的我对这个解决方案非常满意. (5认同)

Con*_*ngo 11

请参阅DllExport

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

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


Fil*_*ącz 5

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

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

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

  • 好的答案,糟糕的教程.如果可能,请链接到更好的教程:) (2认同)