我在使用wineg++
. 为了说明我的问题,我编写了两个测试程序。
消息框.cpp
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <windows.h>
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
char buf[30], *pos = buf;
int xs[] = {1,3,2,4,3,5,4,6,5,7,6,8,7,9};
std::sort( std::begin(xs), std::end(xs) );
for (int x : xs) {
pos += std::sprintf(pos, "%d ", x);
}
MessageBox(0, buf, "Hello", 0);
return 0;
}
框架.cpp
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
CWinApp winApp;
CFrame frame;
CWnd view;
frame.SetView(view);
frame.Create();
winApp.Run();
}
第二个程序使用Win32++库,我推荐的不够多。
两个程序都可以使用交叉编译器编译和运行:
okuu% x86_64-w64-mingw32-g++ msgbox.cpp -o msgbox.exe
okuu% wine ./msgbox.exe
okuu% x86_64-w64-mingw32-g++ frame.cpp -o frame.exe -lgdi32 -lcomctl32 -static
okuu% wine ./frame.exe
okuu% rm *exe*
但我想使用winelib
这样我就可以同时使用 Windows API 和 Unix 库。这是我首先尝试的:
okuu% wineg++ msgbox.cpp -o msgbox.exe
okuu% ./msgbox.exe
okuu% wineg++ frame.cpp -o frame.exe -mwindows
In file included from ../win32xx/include/wxx_appcore.h:57:0,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
../win32xx/include/wxx_appcore0.h:120:12: fatal error: process.h: No such file or directory
#include <process.h>
^~~~~~~~~~~
compilation terminated.
winegcc: g++ failed
然后我阅读了wineg++
的手册页,上面写着:
-mno-cygwin
使用 MSVCRT 的 Wine 实现,而不是链接到主机系统 libc。这对于绝大多数 Win32 应用程序来说都是必需的,因为它们通常依赖于 MSVCRT 的各种功能。MinGW 编译器也使用此开关链接到 Windows 上的 MSVCRT,而不是链接到 Cygwin libc。与 MinGW 共享语法使得编写在 Wine、MinGW+MSYS 或 MinGW+Cygwin 下工作的 Makefile 变得非常容易。
因此,我再次尝试使用-mno-cygwin
,并收到一条 2000 行的错误消息,开头为:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cstdlib:75:0,
from /usr/include/c++/7.2.1/bits/stl_algo.h:59,
from /usr/include/c++/7.2.1/algorithm:62,
from ../win32xx/include/wxx_appcore0.h:110,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
/usr/include/stdlib.h:310:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *fptr; /* Front pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:311:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *rptr; /* Rear pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:312:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *state; /* Array of state values. */
^~~~~~~
wint_t
/usr/include/stdlib.h:316:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *end_ptr; /* Pointer behind state table. */
^~~~~~~
wint_t
/usr/include/stdlib.h:320:8: error: ‘int32_t’ has not been declared
int32_t *__restrict __result) __THROW __nonnull ((1, 2));
^~~~~~~
所以似乎 C99 的固定大小整数类型不可用。这似乎很容易解决:
框架.cpp
#include <stdint.h>
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
// etc. etc. etc.
我又试了一次,但收到一条不同的 2000 行错误消息,开头为:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cwchar:44:0,
from /usr/include/c++/7.2.1/bits/postypes.h:40,
from /usr/include/c++/7.2.1/bits/char_traits.h:40,
from /usr/include/c++/7.2.1/string:40,
from ../win32xx/include/wxx_appcore0.h:111,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:2:
/usr/local/include/wine/msvcrt/wchar.h:398:23: error: conflicting declaration of C function ‘size_t mbstowcs(wchar_t*, const char*, size_t)’
size_t __cdecl mbstowcs(wchar_t*,const char*,size_t);
^~~~~~~~
在这一点上,我已经没有想法了。这是我到目前为止所理解的:
- 我系统的 libc 和 Wine 的 MSVCRT 有冲突的定义。(这可能是意料之中的。)
- 我系统的 libc++ 硬连线可以与我系统的 libc 一起工作。
- Wine 带有 MSVCRT,但不带有 C++ 标准库实现。
到目前为止,根据我所掌握的信息,合乎逻辑的做法是寻找与 Wine 的 MSVCRT 兼容的 C++ 标准库实现,但我不知道有哪一种。这里有人知道吗?