2

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

为此,我知道我需要创建morag.dll.spec文件并将其构建到morag.dll.so.

按照此处的说明,我创建了一个morag.c包含函数的包装器ProxyfooProxybar它除了调用真正的函数 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

注意 [..] 表示我只在我也在构建 c 部分的情况下使用它。

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

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

非常感谢所有帮助。

4

1 回答 1

0

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

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

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

生成的 .def 文件必须与其他对象一起链接到 morag.dll.so。这可以完成工作。

于 2018-08-24T21:01:53.280 回答