Wine spec files

2020-07-23 06:12发布

问题:

I have a Windows DLL called morag.dll containing functions foo and bar. I also have a Linux SO called morag.so containing the Linux implementations of foo and bar (same parameters on each platform). I have a Windows application that loads morag.dll that I want to run under wine. The application itself runs fine, however I need to create the mapping between foo and bar which are expected by my application to be found in morag.dll to instead use foo and bar in morag.so.

To do this I know I need to create morag.dll.spec file and winebuild it into morag.dll.so.

Following instructions here I created a wrapper in morag.c containing functions Proxyfoo and Proxybar which do nothing more than call real functions foo and bar. Then I created morag.dll.spec thus:-

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

I compiled my c part, winebuild the spec file, and then use winegcc to link them into morag.dll.so

Then I read this page which suggested you maybe didn't need the proxy function so I tried without the c part altogether and made a spec file thus:-

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

And as above, did the winebuild step and the winegcc link step.

In both cases these were the options I used.

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. [..] denotes I only used this in the case where I was also building the c part.

in both cases, when my application running under wine tries to load the entry point in the DLL using GetProcAddress it fails.

I ran wine with WINEDEBUG=+module,+relay and saw the attempt and failure recorded as follows:-

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

It seems it has found and loaded my morag.dll.so since LoadLibraryExA has returned the handle to it, but when it tries to find function foo within that HMODULE handle it fails.

If I issue:-

nm -D morag.dll.so

I see foo and bar shown as U in both cases. In the case where there are proxy functions as well, the proxy functions are shown as T.

I assume that this is because I have not built the morag.dll.so file correctly, either with the wrong options, or that my spec file is not correctly formed. I am not sure which of the two schemes described above I should be using.

All help most appreciated.

回答1:

I ran into the same problem today.

What was missing in my case was the proper exporting rule for e.g. foo and bar in the built-in DLL. Conveniently, besides the --dll object, the winebuild tool can create a .def file for us, e.g.:

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

The resulting .def file must be linked into morag.dll.so along with other objects. This does the job.



标签: dll wine winelib