葡萄酒规格文件

时间:2016-12-16 02:24:47

标签: dll wine winelib

我有一个名为morag.dll的Windows DLL,其中包含函数foo和bar。我还有一个名为morag.so的Linux SO,其中包含foo和bar的Linux实现(每个平台上的参数相同)。我有一个Windows应用程序加载我想在wine下运行的morag.dll。应用程序本身运行正常,但我需要创建foo和bar之间的映射,我的应用程序可以在morag.dll中找到它,而不是在morag.so中使用foo和bar。

要做到这一点,我知道我需要创建morag.dll.spec文件并将其构建到morag.dll.so

按照说明here我在morag.c中创建了一个包含函数ProxyfooProxybar的包装器,它除了调用实际函数foo和bar之外什么也没做。然后我创建了morag.dll.spec: -

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

我编译了我的c部分,winebuild spec文件,然后使用winegcc将它们链接到morag.dll.so

然后我读了this page,这表明你可能不需要代理功能,所以我尝试了完全没有c部分并制作了一个spec文件: -

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开酒,看到尝试和失败的记录如下: -

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文件,使用错误的选项,或者我的spec文件没有正确形成。我不确定我应该使用上述两种方案中的哪一种。

非常感谢所有帮助。

1 个答案:

答案 0 :(得分:0)

我今天遇到了同样的问题。

我的案例中缺少的是适当的出口规则,例如内置DLL中的foobar。方便地,除了--dll对象之外,winebuild工具还可以为我们创建一个.def文件,例如:

morag.def: morag.spec
    $(WINEBUILD) --def -E $< -o $@

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