下面讲一下我们的Windows项目的可移植性问题。总共从三个方面来讲这个问题。
- Unicode编码
- C库
- 编译问题
(一):Unicode编码
wchar_t类型在Unix(4字节)和Windows(2个字节)中有不同的标准大小。你需要一个较新版本的gcc(2.9.7或者是更新)来支持-fshort-wchar选项来设置wchar_t的大小。
如果你正在使用Unicode编码,并且你想要能够使用标准的库函数调用,你一定要使用msvcrt运行库而不是glibc。在glibc中的函数对16位的字符串不能很好的运行。
(二):C库
对于使用哪一个C库你现在有两个选择:本地glibc库和msvcrt C库。
注意在Wine下,crtdll库是使用msvcrt来实现的,所以,尝试使用它是没有好处的。
使用glibc一般具有最低开销,但是这仅仅对I/O是非常重要的,因为在msvcrt中的一些函数就是简单的解析成了glibc。
为了使用glibc,你不必对你的应用去做改变;他应该是直接可以工作的。下面有几个情况使用gibc是不可能的:
- 你的应用使用Win32和C库的unicode函数
- 你的应用使用MS专门的调用例如beginthread(),loadlibrary()等等
- 你依赖于调用的精确语义,例如,返回-1而不是非0.更有可能的是,你的应用依赖于调用像fopen()采用Windows路径而不是Unix路径的函数。
在这些情况下,你应该使用msvcrt来提供你的C运行调用。
添加一个 -mno-cygwin到你的编译器标志中。这个能够使得winebuild解决你的C库调用msvcrt.dll。一些简单的运行效果一样的调用已经从msvcrt中被指定成为非重要性的。在这种情况下,winebuilder讲不会处理他们,标准链接器ld将会讲他们链接到glibc中。
为了避免因为没有原型而导致在C(和在C++中潜在的错误)中的警告,你需要使用一系列的MS兼容的头文件。这些都是预定的纳入到wine中,但是在编写的时候是不可用的。你可以尝试使用你需要的原型的函数或者是仅仅在警告中。
如果你有一系列的包含文件(或者是他们在Wine中是可用的),你需要在gcc中使用-isystem 包含的路径 来告诉他使用你的头文件引用。为了使用选项3,添加任何你不想从msvcrt中使用的符号的名称到你的应用的.spec文件中。举个例子,你过你想要使用MS专用函数,但不是文件I/O,你可以这样使用:
@ignore = (fopen,fclose,fwrite,fread,fputs,fgets)
很明显,完整的列表会更长。记住一些函数在他们的名称中使用下横线实现的,有的是在MS头文件中#define宏定义的。所以你可能需要通过检查dlls/msvcrt/msvcrt.spec来位你的@ignore元素找到正确的名称。
(三):编译问题
当你构建你的应用的时候,如果你的到对Win32 API未定义的引用:如果你有一个VC++的.dsp文件,检查他引入的所有的.lib文件,然后讲他们添加到你的应用的.spec文件中。winebuild对于未使用的引入将会给出一个警告,所以在后面你不需要的话可以删除他。如果失败了,你就把在Wine源码树里面的你能找到的所有的DLLS文件都引进来。如果你在链接阶段丢失了GUIDS,在链接行中添加选项-luuid。
gcc要比VC++更严格,特别是在编译C++的时候。这可能要求你在你的C++中添加强制访问来阻止相似类型间的重载模糊(例如两个重载分别采用int和char)。
如果你遇到了在Windows和Wine头文件的不同而中断了编译,尝试询问wine-devel@winehq.org来寻求帮助。