首页 > 解决方案 > 跨平台 C++ 是否需要在每个平台上单独构建?

问题描述

我的问题实际上有两个变体,但在某些情况下,我有一个 C++ *.DLL,我使用 p/Invoke 与 Unity 一起使用。它使用 MSBuild(平台工具集:ClangCL)在 Windows 10 上构建。

现在对于我的问题,

  1. 在构建 DLL之后,特定类型的大小是否保持不变?还是需要在目标平台(比如 Linux 或 Mac)上重新构建?

我的代码看起来有点像这样:

typedef wchar_t wchar;
static_assert(sizeof(wchar) == 2, "WideChar size-test failed.");

在 Windows 上重新编译源代码后,如果我为 Android 平台构建 Unity 项目,wchar 的大小是否也会保持不变?或者,当我的字符串处理代码停止工作时,我是否会大吃一惊?

  1. 构建 DLL 后是否保留了一些其他语言功能,或者我是否需要更改我的工作流程以解决其他问题?

特别是,让我们看一些超级基础的东西,比如外部方法。

#define CALLING_CONVENTION __stdcall

#if _WIN32
#define DLLEXPORT(type) extern "C" __declspec(dllexport) type CALLING_CONVENTION
#else
#define DLLEXPORT(type) extern "C" type CALLING_CONVENTION
#endif

DLLEXPORT(void) DoSomething(const wchar* ManagedString);
// expands to
// extern "C" __declspec(dllexport) void __stdcall DoSomething(const wchar* ManagedString)
// on Windows

对于托管,

[DllImport("DllName", CharSet = CharSet.Unicode)]
public static extern void DoSomething([MarshalAs(UnmanagedType.LPWStr)] string input);

这是否也会保持其他平台的互操作性?还是我需要不遗余力地在 Linux 上构建 C++ DLL,然后将用于 Android 平台?

标签: c#c++unity3dcross-platforminterop

解决方案


每个平台通常都有不同的ABI。例如,long在 Windows 上是 32 位(来自内存),但long在 Linux 上是 64 位。在您的示例中,wchar_t在 Windows 上是 16 位,但在 Linux 上是 32 位。C++ 名称被破坏的方式也是特定于平台的。

Windows 和 Linux 都有不同的系统调用(标准库函数,如malloc通常最终调用特定于平台的系统调用)。但不仅如此,每个平台存储和加载可执行代码的方式(以及它如何动态链接到其他可执行代码)也不同,并且如果没有某种中间的翻译器(例如WINE),通常无法运行为不同平台编译的可执行代码。

所以一般来说,你需要为你打算支持的每个平台编译你的代码。另请参阅Unity 论坛中的此帖子


推荐阅读