Rui*_*ira 3 c# c++ swig .net-core
随着 .net Core 和最近 .net 5 的推出,跨平台 .net/C# 相对容易。考虑到这一点,我正在开发一个使用 .net 5/C# 的应用程序,但我想将一些代码保留在 C++/本机域中。仅使用 C#,甚至可以从开发平台发布到其他平台。我愿意放弃这一点。
现在,如何才能保持项目的跨平台性呢?
我一直在到处寻找,但似乎没有什么好的选择......
也许这个解决方案来自 Xamarin?我不确定它会转换为桌面,或者它可以在 CI/CD 上自动化......
但除此之外,每个人似乎都以自己的方式逃脱惩罚。
有人有关于跨平台 C(++)/C# 集成的指导吗?
编辑1:
我的问题不是进行互操作本身。我已经成功使用了 SWIG,并且了解 P/Invoke、C 兼容的 ABI 等。
我的问题是构建系统/部署。到目前为止我必须复制文件。但如何才能拥有一个集成的构建系统呢?例如,我希望在构建要编译的 C++ 库的 dotnet 应用程序时做到这一点。
您可以毫无问题地使用 C++/C#。但是 C++ 端和 C# 端之间的“桥梁”方法必须接受/返回纯 C 类型/结构。你不能跳过std::xxxx句号。可以转转char *str,,struct { int Foo, int Bar }int[](但仍然有一点复杂,具体取决于它的完成方式)。
我维护着一个github示例,其中包含有关在 .NET Framework/.NET Core 上从 C/C++ 到 C# 封送字符串和结构的示例。该项目是为 Visual Studio 构建的,因此内部有一些“微软性”,但基本思想可以轻松复制粘贴到其他 C 平台上。
当您想要做一个完全多平台的项目时,还有一些额外的复杂性(当我编写这些示例时,我没有考虑跨平台):
字符串的编码:在示例中,我展示了您可以轻松地使用 utf-8 字符串,但这仍然是一个痛苦,因为在 Windows 上,Windows API 不支持 utf-8 并且是为wchar_t(您不能CreateFile使用utf-8 文件名)。另一方面,Linux 上每个人都使用char*,但几乎没有人使用wchar_t*(举同一个例子,Linux 上的文件系统与字符集无关,因此open原语和fopen方法可以接受char*utf-8 编码),因此决定如何以跨平台的方式处理char/wchar_t是一种痛苦。如果我必须这样做,我可能会在 Linux 和Windows 上定义TCHAR宏,在任何地方使用它,并使用字符串的编组选项和类的方法(例如)。.NET Core 认为/既可以在 Linux 上运行,也可以在 Windows 上运行。charwchar_tLPTStrAutoMarshalMarshal.PtrToStringAutoLPTStrxxxAutochar*wchar_t*
在 Windows 上有大量的内存分配器(.NET Core 在互操作中使用的主要分配器是 forCoTaskMemAlloc内存和SysAllocStringfor 字符串,但也有一些利基(useles)的东西,例如GlobalHAlloc),而在 Linux 上 .NET Core 直接使用malloc. 这对于释放“从另一端”分配的内存非常重要,并且如果您希望能够让编组器自动释放内存,则会增加复杂性。但最终从 C/C++ 端公开内存释放器始终是一个好主意,因为在此之前或之后您必须释放在 C/C++ 端分配的内存。虽然可能,但我认为让编组器自动释放分配给 C/C++ 端的内存是一个坏主意(因为您无法控制操作,并且无法轻松调试它)。因此,没有char* Foo()用 C# 翻译string Foo():可以做到这一点,但 .NET 编组器将使用CoTaskMemFree它来释放它。还有其他方法可以执行此操作,或者您可以手动执行此操作(IntPtr Foo()然后IntPtr显式转换并释放)。
BSTR在Linux下使用and有一些限制SAFEARRAY(主要问题是C端没有相互的方法),所以如果你想跨平台编程,使用它们是一个坏主意(但没有人使用它们)