c# - 跨平台 C++ 是否需要在每个平台上单独构建?
问题描述
我的问题实际上有两个变体,但在某些情况下,我有一个 C++ *.DLL,我使用 p/Invoke 与 Unity 一起使用。它使用 MSBuild(平台工具集:ClangCL)在 Windows 10 上构建。
现在对于我的问题,
- 在构建 DLL之后,特定类型的大小是否保持不变?还是需要在目标平台(比如 Linux 或 Mac)上重新构建?
我的代码看起来有点像这样:
typedef wchar_t wchar;
static_assert(sizeof(wchar) == 2, "WideChar size-test failed.");
在 Windows 上重新编译源代码后,如果我为 Android 平台构建 Unity 项目,wchar 的大小是否也会保持不变?或者,当我的字符串处理代码停止工作时,我是否会大吃一惊?
- 构建 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 平台?
解决方案
每个平台通常都有不同的ABI。例如,long
在 Windows 上是 32 位(来自内存),但long
在 Linux 上是 64 位。在您的示例中,wchar_t
在 Windows 上是 16 位,但在 Linux 上是 32 位。C++ 名称被破坏的方式也是特定于平台的。
Windows 和 Linux 都有不同的系统调用(标准库函数,如malloc
通常最终调用特定于平台的系统调用)。但不仅如此,每个平台存储和加载可执行代码的方式(以及它如何动态链接到其他可执行代码)也不同,并且如果没有某种中间的翻译器(例如WINE),通常无法运行为不同平台编译的可执行代码。
所以一般来说,你需要为你打算支持的每个平台编译你的代码。另请参阅Unity 论坛中的此帖子。
推荐阅读
- javascript - Jquery从ajax调用中获取文件名
- r - ggplot:将ylab旋转并重新定位到中间
- javascript - ReactJS如何验证所有输入然后提交
- php - 成功提交表单,但控制台出现一个错误,例如 A Database Error Occurred Error Number: 1048 - Codeigniter
- arrays - 查找 MongoDb 文档中数组中第一个位置的所有不同值
- java - 如何使这个算法变得懒惰?(爪哇)
- javascript - 将值从一个输入字段传递到另一个
- javascript - 如何将 2 个数组与猫鼬合并?
- visual-foxpro - 根据另一个字段的最大值选择记录
- excel - 在这个命名约定中加入 Worksheetfunction.right?