跨平台 C++ 是否需要在每个平台上单独构建?

Does cross-platform C++ require building separately on every single platform?

我的问题实际上有两个变体,但在某些情况下,我有一个 C++ *.DLL 与 Unity using P/Invoke. It's built on Windows 10 with MSBuild(平台工具集:ClangCL)一起使用。

现在回答我的问题,

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

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

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

我在Windows上重新编译源代码后,如果我为Android平台构建Unity项目,wchar的大小会保持不变吗?那里也一样吗?还是当我的字符串处理代码停止工作时,我感到非常惊讶?

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

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

#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,然后将 that 用于 Android 平台?

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

Windows 和 Linux 都有不同的系统调用(像 malloc usually end up calling platform-specific syscalls). But not only that; the way that each platform stores and loads executable code (and how it dynamically links to other executable code) is also different, and without some sort of translator in between (such as Wine 这样的标准库函数),通常不可能 运行 为不同系统编译的可执行代码平台。

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