Wine规范文件

3
我有一个Windows DLL叫做morag.dll,其中包含函数foo和bar。我还有一个名为morag.so的Linux SO,其中包含foo和bar的Linux实现(每个平台上的参数相同)。我有一个加载morag.dll的Windows应用程序,我想在wine下运行它。应用程序本身可以正常运行,但我需要创建映射,将应用程序中期望在morag.dll中找到的foo和bar使用morag.so中的foo和bar代替。
为此,我知道需要创建morag.dll.spec文件,并将其winebuild成morag.dll.so文件。
根据这里的说明,我创建了一个包含函数ProxyfooProxybarmorag.c包装器,这些函数仅调用真正的函数foo和bar。然后我创建了morag.dll.spec文件,如下所示:
1 stdcall foo (long ptr) Proxyfoo
2 stdcall bar (ptr ptr)  Proxybar

我编译了我的C代码部分,使用winebuild编译了规范文件,然后使用winegcc将它们链接成morag.dll.so

然后我阅读了这个网页,其中建议你可能不需要代理函数,因此我尝试完全不使用C代码部分,并制作了以下规范文件:

1 stdcall foo (long ptr)
2 stdcall bar (ptr ptr)

就像上面所述,我完成了winebuild步骤和winegcc链接步骤。

在这两种情况下,我使用了以下选项。

winebuild --dll -m32 -E ./morag.dll.spec -o morag.dll.o

ldopts= -m32 -fPIC -shared -L/usr/lib/wine -L/opt/morag/lib -lmorag

winegcc $(ldopts) -z muldefs -o morag.dll.so [morag.o] morag.dll.o

N.B. [..] 表示我只在同时构建C部分的情况下使用此项。

在这两种情况下,当我的应用程序在wine环境下运行并尝试使用 GetProcAddress 加载DLL中的入口点时,它会失败。

我使用 WINEDEBUG=+module,+relay 运行了wine,并在记录中看到了以下尝试和失败的信息:

0025:Ret  KERNEL32.LoadLibraryExA() retval=7dbc0000 ret=00447b84
0025:Call KERNEL32.GetProcAddress(7dbc0000,00b2d060 "foo") ret=00447c8a
0025:Ret  KERNEL32.GetProcAddress() retval=00000000 ret=00447c8a

看起来它已经找到并加载了我的morag.dll.so,因为LoadLibraryExA已经返回了它的句柄,但是当它尝试在那个HMODULE句柄中查找函数foo时失败了。

如果我发出以下命令:

nm -D morag.dll.so

我看到foo和bar在两种情况下都显示为U。如果还有代理函数的情况下,代理函数会显示为T。

我猜想这是因为我没有正确地构建morag.dll.so文件,可能是因为选项错误或者我的规范文件格式不正确。我不确定我应该使用上述两种方案中的哪一种。

非常感谢任何帮助。

1个回答

0
今天我遇到了同样的问题。
在我的情况下缺少的是内置 DLL 中例如 foobar 的适当导出规则。方便的是,除了 --dll 对象之外,winebuild 工具还可以为我们创建 .def 文件,例如:
morag.def: morag.spec
    $(WINEBUILD) --def -E $< -o $@

生成的 .def 文件必须与其他对象一起链接到 morag.dll.so 中。这样就完成了任务。


请注意,这个问题与 https://stackoverflow.com/questions/46380191/wine-cant-load-my-custom-build-in-dll-and-report-call-to-unimplemented-functio 大致相同,对此相同的回答可能有所帮助。 - Dmitry Mikushin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接