如何使用 Mono/C# 程序调用 linux/c++ 函数?

Posted

技术标签:

【中文标题】如何使用 Mono/C# 程序调用 linux/c++ 函数?【英文标题】:How to call linux/c++ function with Mono/C# program? 【发布时间】:2017-03-20 10:28:20 【问题描述】:

我用谷歌搜索了很多,但找不到解决我非常具体的问题的方法,至少它似乎非常具体。 我有以下情况:

ARM 板上的嵌入式 Linux (Debian)。我正在运行“旧”C++ 应用程序,它们通过 CAN 总线和 SocketCAN API 发送和接收数据。

但最近我使用 C# 处理了一些项目,并且非常喜欢 .NET 框架,这就是我在嵌入式系统上安装 Mono 的原因。 运行纯 C# 应用程序没有问题。

但现在我想通过 Mono/C# 应用程序访问 CAN 总线,这似乎是个问题,因为没有 api 作为 socketcan。这就是为什么我有想法调用创建和处理底层 Socket 操作的 c++ 函数,而我的 C# 程序处理数据。

我发现了诸如调用 c++ 函数或将 c++ 函数/类编译为 DLL 并在 C# 中调用它们之类的东西。问题是,我还没有找到如何将我的 SocketCAN/C++ 程序编译成 DLL 的解决方案,因为我的主机 Windows 机器上的 Visual Studio 编译器显然不知道 linux 内核可以实用程序。

那么有人知道我该如何解决这个问题吗?我可以看到可能有更多解决方案,但我想不出一个。

【问题讨论】:

你不需要编译成dll。您也可以使用常规 pinvoke 从(例如).so 文件调用函数。 请注意,最后,.so 对于 Linux 就像 .dll 对于 Windows:它们是程序可以使用的动态库。 谢谢!我写了一个包含我的函数的 lib.so 文件,但是当我尝试用我的 c# 程序调用它们时,我得到 System.EntryPointNotFoundException。我想这是因为我用 [code] extern "C" __declspec(dllexport)[/code] 声明了我的函数,这在某种程度上似乎适用于 Windows。什么是正确的声明? @rele92 我在下面编辑了我的答案 【参考方案1】:

您的库是什么样的?你能从他们那里创建.so 吗?如果是,那么一切都很好。据我所知,MONO 可以处理适当级别的互操作。

MONO Interop

请注意,您应该注意调用约定(link1、link2)并可能使用完整的形式:

[DllImport("mylib.so", EntryPoint = "my_func1", CallingConvention = CallingConvention::Cdecl,  CharSet = CharSet::Ansi)]

对于您的extern "C",我想Cdecl 是合适的(如果不是,请检查其他人^-^)

从上面的 MONO 文档的链接:

可以通过在 Microsoft Visual C++ 下使用 __stdcall__cdecl 编译器内在函数以及在 GCC 下使用 __attribute__((stdcall))__attribute__((cdecl)) 编译器内在函数在 C 代码中指定调用约定。

免责声明:我不使用 MONO(我也不知道您使用的是什么 C/C++ 编译器),所以您需要检查一下。

【讨论】:

以上是关于如何使用 Mono/C# 程序调用 linux/c++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章

Linux Mono C#错误:无法打开程序集'Bovine.csproj':文件不包含有效的CIL图像

Mono c# 获取类

linux c ++如何在特定时间间隔后调用函数

linux c开发: 在程序退出时进行处理

linux c 用户态调试追踪函数调用堆栈以及定位段错误

Linux C fork exec介绍用法