繁体   English   中英

跨平台 C++ 在 C# .net Core/5 应用

[英]Cross platform C++ in C# .net Core/5 application

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

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

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

也许这个解决方案来自 Xamarin 我不确定它会转化为桌面,或者它可以在 CI/CD 上自动化......

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

有人对跨平台的 C(++)/C# 集成有什么建议吗?

编辑1:

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

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

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

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

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

  1. The encoding of strings: in the examples I show that you can use utf-8 strings easily, but it is still a pain, because on Windows the Windows API don't support utf-8 and are tailored for wchar_t (you can't CreateFile with an utf-8文件名)。 On the opposite side on Linux everyone uses char* and nearly no one uses wchar_t* (to give the same example, filesystems on Linux are agnostic about character sets , so the open primitive and the fopen method can accept char* that can be utf-8 encoded ),因此决定如何以跨平台方式处理char / wchar_t是一件痛苦的事情。 If I had to do it, I would probably define the TCHAR macro to be char on Linux, wchar_t on Windows, use it everywhere, and use the LPTStr marshalling option for strings, and the Auto methods for the Marshal class ( Marshal.PtrToStringAuto for例子)。 .NET 内核将LPTStr / xxxAuto视为 Linux 上的char*和 Windows 上的wchar_t*

  2. While on Windows there is a great deluge of memory allocators (the main ones used by .NET Core in interop are the CoTaskMemAlloc for memory and the SysAllocString for strings, but there are niche (useles) things like GlobalHAlloc ), on Linux .NET Core uses directly malloc 这对于释放“从另一侧”分配的 memory 很重要,如果您希望能够让编组器自动释放 memory,则会增加复杂性。 但最终,从 C/C++ 端公开 memory 释放器总是一个好主意,因为在此之前或之后,您必须释放在 C/C++ 端分配的 memory。 虽然可能,但我认为让编组器自动释放 memory 分配的 C/C++ 端是一个坏主意(因为您无法控制操作,并且无法轻松调试它)。 所以没有char* Foo()string Foo()在 C# 中翻译:可以这样做,但是 .NET 编组器将使用CoTaskMemFree来释放它。 还有其他方法可以做到这一点,或者您可以手动进行( IntPtr Foo() ,然后显式转换并释放IntPtr )。

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

有三个方面:

  1. .NET/本机互操作
  2. 原生组件库的部署和打包
  3. 部署整个应用程序包,即托管和本地部分

显然,您需要为所有受支持的平台维护本机组件的版本和构建。 这本身就是一个挑战,但与从 .NET 使用它无关。 关于 1),您需要为与标准化 PInvoke 规范兼容的本机库提供 API。 这可能具有挑战性,具体取决于您的组件所做的事情,如果做得不好,可能会导致麻烦。 如果可以,请只选择纯托管代码,如果您已准备好迎接挑战,请继续!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM