如何使用 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++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章