比较
下面是对运行于 Windows XP 上的和运行于 Red Hat 的 GNOME 中的消息框(Message Box)视觉上的对比:
对应于此的 C 代码(callDll.cpp 中第 60 行):
MessageBox(NULL, "Wine test ending...", "", MB_OK);
这提出了一些有趣的观察:
最明显的观察之一是,双方都支持消息框的使用;这是将 Windows 调用有可能映射为 Linux 中相应部分的因素之一。如果您在 Wine 源代码中搜索 MessageBox,您可以找到说明文件,文件中详细说明了哪些函数已经被实现,哪些被去除掉。
大小、字体、颜色和标题栏以及其他可视元素继承自底层操作系统设置的默认值。
从本文中所包括的追踪文件中,您可以看到这个函数是在 user32.dll 中实现的。如果您在文件中搜索字符串“Wine test ending”,您将更深入地理解到,当您在做一些与在消息框中显示字符串同样简单的事情时,幕后发生了多少事情。
既然我们已经看过了一个 Win32 函数,让我们来看一下,当 simpleDLL.dll 中实现的我们自己的函数之一被调用时,幕后发生了什么。我们将展示追踪记录中的片断来说明何时 simpleDll.dll 被加载,哪些函数被导出,在哪一点 getTitle() 函数被调用(按 README 文件中的步骤生成完全的追踪记录):
清单 2. 解析出我们的 DLL 的路径并检查 DLL 是否存在
以下为引用的内容:
0009:trace:module:MODULE_GetLoadOrder looking for
C:\documents\article-sample\simpleDLL.dll
清单 3. 这一行展示我们的 DLL 所导出的函数
以下为引用的内容:Module name is simpleDLL.dll, 3 functions, 3 names
Ord RVA Addr Name
1 0000100a 0x1000100a add
2 0000100f 0x1000100f getSize
3 00001014 0x10001014 getTitle
清单 4. 这里展示了 getTitle 被调用的位置
以下为引用的内容:0009:CALL simpleDLL.getTitle((0x40580000,00000002,00000040):
returning 405b7210
) ret=004010d4
0009:RET simpleDLL.getTitle() retval=1002901c ret=004010d4
分析一个更大的应用程序或多或少与此相似,不过您当然会得到多得多的细节,会遇到没有被实现的函数,等等。故障诊断通常大概是提供缺少的 DLL 和调整配置;偶尔,您将需要去实现或修复一个函数。
结束语
如果您正在寻找将现有的 Windows 应用程序转移到 Linux 的方法,开放源代码的 Wine 和来自 CodeWeavers 的商用产品都是极好的选择。应用程序可以运行于 Wine 之上,或者使用 Winelib 工具包进行移植。