c# - C# .net Core/5 应用程序中的跨平台 C++

标签 c# c++ .net-core swig

随着 .net Core 以及最近的 .net 5 的推出,跨平台 .net/C# 相对容易。 考虑到这一点,我正在开发一个将使用 .net 5/C# 的应用程序,但我想在 C++/ native 域中保留一些代码。仅使用 C#,甚至可以从开发平台发布到其他平台。我愿意为此放弃。

现在,如何才能使项目保持跨平台?

我到处都在寻找,似乎没有一个很好的选择...

也许 this solution from Xamarin ?我不确定它是否会转化为桌面,或者它是否可以在 CI/CD 上自动化...

但除此之外,每个人似乎都以自己的笨拙方式逃脱。

有人对跨平台的 C(++)/C# 集成有指点吗?

编辑 1:

我的问题不是制作互操作本身。我已成功使用 SWIG,并且了解 P/Invoke、C 兼容 ABI 等。

我的问题是构建系统/部署。到目前为止,我必须复制文件。但是如何才能拥有一个集成的构建系统呢?例如,在为要编译的 C++ 库构建我的 dotnet 应用程序时,我希望这样做。

最佳答案

您可以毫无问题地使用 C++/C#。但是 C++ 端和 C# 端之间的“桥梁”方法必须接受/返回纯 C 类型/结构。 您不能绕过 std::xxxx 句号。您可以传递 char *strstruct { int Foo, int Bar }int[] 等等(但仍然有一个不太复杂,具体取决于它是如何完成的)。

我维护一个 github关于在 .NET Framework/.NET Core 上将字符串和结构从 C/C++ 编码到 C# 的示例。该项目是为 Visual Studio 构建的,因此内部有一些“微软特性”,但基本思想可以很容易地复制粘贴到其他 C 平台上。

当你想做一个完全多平台的项目时,还有一些额外的复杂性(我在写这些例子时没有考虑跨平台):

  1. 字符串的编码:在示例中我展示了您可以轻松地使用 utf-8 字符串,但这仍然是一个痛苦,因为在 Windows 上,Windows API 不支持 utf-8 并且是为wchar_t(您不能使用 utf-8 文件名CreateFile)。相反,在 Linux 上每个人都使用 char* 而几乎没有人使用 wchar_t*(举同样的例子,filesystems on Linux are agnostic about character sets,所以 open 原语和fopen 方法可以接受可以utf-8编码的char*),所以决定如何处理char/wchar_t 以跨平台的方式是一种痛苦。如果必须这样做,我可能会在 Linux 上将 TCHAR 宏定义为 char,在 Windows 上将其定义为 wchar_t,在任何地方都使用它,并且对字符串使用 LPTStr 编码选项,对 Marshal 类使用 Auto 方法(例如 Marshal.PtrToStringAuto ). .NET Core 将 LPTStr/xxxAuto 视为 Linux 上的 char* 和 Windows 上的 wchar_t*

  2. 虽然在 Windows 上有大量的内存分配器(.NET Core 在互操作中使用的主要分配器是用于内存的 CoTaskMemAllocSysAllocString对于字符串,但在 Linux 上有像 GlobalHAlloc 这样的利基(无用)东西,.NET Core 直接使用 malloc。这对于释放“从另一端”分配的内存很重要,如果您想让编码器自动释放内存,它会增加复杂性。但最后,从 C/C++ 端公开内存释放器始终是一个好主意,因为在此之前或之后,您将不得不释放在 C/C++ 端分配的内存。虽然可能,但我认为让编码器自动释放分配给 C/C++ 端的内存是个坏主意(因为您无法控制操作,并且无法轻松调试它)。所以没有 char* Foo() 在 C# 中用 string Foo() 翻译:这是可能的,但是 .NET 编码器将使用 CoTaskMemFree 释放它。还有其他方法可以做到这一点,或者您可以手动完成(IntPtr Foo(),然后显式转换并释放 IntPtr)。

  3. 在Linux下使用BSTRSAFEARRAY有一些限制(主要问题是C端没有对等方法),所以如果你想跨平台编程使用它们不是一个好主意(但没有人使用它们)

关于c# - C# .net Core/5 应用程序中的跨平台 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65968143/

相关文章:

c# - 从 Controller 调用 SignalR Core Hub 方法

c# - 为什么我不能将不同数量的引用传递给一个函数?

c# - 线程的命名约定?

java - 从 Java 调用 C、C++ 程序

c# - 服务器端 .NET Core 中的 Session.SetString() 产生错误 "The session cannot be established after the response has started"

c# - 反转数组中的元素

android - QVideoFrame::map() 崩溃

c++ - Visual Studio 调试器正在卸载 DLL 的符号

.net-core - 升级到 2.1 后,dotnet core cpu 利用率发生了巨大变化

c# - 为什么 Logging 不使用字符串插值