I am having a problem compiling a simple winelib program which relies on a dll which uses the stdcall calling convention. I used pexports on the dll avisynth_c.dll to created the spec and then edited the file to removed the leading underscore in the names (without that it would not link). That file is attached. Than with only "avisynth_c.h", "avs2yuv.cpp" and "libavisynth_c.def" in the current directory. I ran winemaker --console -iavisynth_c --single-target avs2yuv.exe . ./configure --with-wine=/opt/wine/ make then I copy the required DLL in the current directory and attempt to run it. But I get:
./avs2yuv err:module:import_dll No implementation for avisynth_c.dll.avs_create_script_environment imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_video_info imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_invoke imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_value imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_video_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_take_clip imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef Usage avs2yuv4mpeg <avsfile> <outfile>
Does anyone know what is going on. Here is the output of make if it will help:
sed -e 's,@bindir@,/usr/local/bin,g' -e 's,@winelibdir@,.,g' ./wineapploader.in >wineapploader || rm -f wineapploader LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -o avs2yuv.exe.dbg.c --debug -C. avs2yuv.cpp gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.dbg.o avs2yuv.exe.dbg.c g++ -c -I. -I/opt/wine//include/wine/windows -g -O2 -fpermissive -fno-for-scope -D_REENTRANT -o avs2yuv.o avs2yuv.cpp LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -fPIC -o avs2yuv.exe.spec.c --exe avs2yuv.exe -mcui avs2yuv.o -L/opt/wine//lib/wine -lavisynth_c gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.spec.o avs2yuv.exe.spec.c g++ -shared -Wl,-Bsymbolic -o avs2yuv.exe.so avs2yuv.o avs2yuv.exe.dbg.o avs2yuv.exe.spec.o -L/opt/wine//lib -lwine -lwine_unicode -lwine_uuid -lm test -f avs2yuv || install ./wineapploader avs2yuv
I attached the zip file with the source and any files I thought were relevant. If required I can send additional files dll's in a private email (such as the required dll's).
Wine version 20031212 built from source on a RedHat System. I had the exact same problem when I used the debs from unstable (also version 20031212) on a libranet system.
Is this a bug, or am I doing something wrong?
When I used a a version of avisynth_c.dll which used cdecl on all API functions -- without changing the .def or header files -- instead of stdlib I do not have this problem. Naturally I do not expect it to run since I didn't recompile my code with the proper header files. I discovered this by accident because the previous version used cdecl and I had some old dll laying around in a place wine was able to find.
Can anyone help me get this working? Am I doing something wrong or is this a bug in wine?
Thanks in advance. --- http://kevin.atkinson.dhs.org
Oops. Sorry that I left the subject off.
On Sun, 21 Dec 2003, Kevin Atkinson wrote:
I am having a problem compiling a simple winelib program which relies on a dll which uses the stdcall calling convention. I used pexports on the dll avisynth_c.dll to created the spec and then edited the file to removed the leading underscore in the names (without that it would not link). That file is attached. Than with only "avisynth_c.h", "avs2yuv.cpp" and "libavisynth_c.def" in the current directory. I ran winemaker --console -iavisynth_c --single-target avs2yuv.exe . ./configure --with-wine=/opt/wine/ make then I copy the required DLL in the current directory and attempt to run it. But I get:
./avs2yuv err:module:import_dll No implementation for avisynth_c.dll.avs_create_script_environment imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_video_info imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_invoke imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_value imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_video_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_take_clip imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef Usage avs2yuv4mpeg <avsfile> <outfile>
Does anyone know what is going on. Here is the output of make if it will help:
sed -e 's,@bindir@,/usr/local/bin,g' -e 's,@winelibdir@,.,g' ./wineapploader.in >wineapploader || rm -f wineapploader LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -o avs2yuv.exe.dbg.c --debug -C. avs2yuv.cpp gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.dbg.o avs2yuv.exe.dbg.c g++ -c -I. -I/opt/wine//include/wine/windows -g -O2 -fpermissive -fno-for-scope -D_REENTRANT -o avs2yuv.o avs2yuv.cpp LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -fPIC -o avs2yuv.exe.spec.c --exe avs2yuv.exe -mcui avs2yuv.o -L/opt/wine//lib/wine -lavisynth_c gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.spec.o avs2yuv.exe.spec.c g++ -shared -Wl,-Bsymbolic -o avs2yuv.exe.so avs2yuv.o avs2yuv.exe.dbg.o avs2yuv.exe.spec.o -L/opt/wine//lib -lwine -lwine_unicode -lwine_uuid -lm test -f avs2yuv || install ./wineapploader avs2yuv
I attached the zip file with the source and any files I thought were relevant. If required I can send additional files dll's in a private email (such as the required dll's).
Wine version 20031212 built from source on a RedHat System. I had the exact same problem when I used the debs from unstable (also version 20031212) on a libranet system.
Is this a bug, or am I doing something wrong?
When I used a a version of avisynth_c.dll which used cdecl on all API functions -- without changing the .def or header files -- instead of stdlib I do not have this problem. Naturally I do not expect it to run since I didn't recompile my code with the proper header files. I discovered this by accident because the previous version used cdecl and I had some old dll laying around in a place wine was able to find.
Can anyone help me get this working? Am I doing something wrong or is this a bug in wine?
Thanks in advance.
I have stdcall working fine here.
There is something wrong with your DLL the fact that "pexports" dumped "_" before symbol names is a clue to those functions been exported as cdecl. In stdcall (or PASCAL) no under-scored is perpended. (and you should see the @number at end of names). check to see how this DLL was compiled on windows (or wine). Was it compiled with a .DEF file?
Kevin Atkinson wrote:
I am having a problem compiling a simple winelib program which relies on a dll which uses the stdcall calling convention. I used pexports on the dll avisynth_c.dll to created the spec and then edited the file to removed the leading underscore in the names (without that it would not link). That file is attached. Than with only "avisynth_c.h", "avs2yuv.cpp" and "libavisynth_c.def" in the current directory. I ran winemaker --console -iavisynth_c --single-target avs2yuv.exe . ./configure --with-wine=/opt/wine/ make then I copy the required DLL in the current directory and attempt to run it. But I get:
./avs2yuv err:module:import_dll No implementation for avisynth_c.dll.avs_create_script_environment imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_get_video_info imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_invoke imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_value imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_release_video_frame imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef err:module:import_dll No implementation for avisynth_c.dll.avs_take_clip imported from L"C:\WINDOWS\SYSTEM\avs2yuv.exe", setting to 0xdeadbeef Usage avs2yuv4mpeg <avsfile> <outfile>
Does anyone know what is going on. Here is the output of make if it will help:
sed -e 's,@bindir@,/usr/local/bin,g' -e 's,@winelibdir@,.,g' ./wineapploader.in >wineapploader || rm -f wineapploader LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -o avs2yuv.exe.dbg.c --debug -C. avs2yuv.cpp gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.dbg.o avs2yuv.exe.dbg.c g++ -c -I. -I/opt/wine//include/wine/windows -g -O2 -fpermissive -fno-for-scope -D_REENTRANT -o avs2yuv.o avs2yuv.cpp LD_LIBRARY_PATH="/opt/wine//lib:$LD_LIBRARY_PATH" /opt/wine//bin/winebuild -fPIC -o avs2yuv.exe.spec.c --exe avs2yuv.exe -mcui avs2yuv.o -L/opt/wine//lib/wine -lavisynth_c gcc -c -I. -I/opt/wine//include/wine/windows -g -O2 -fPIC -D_REENTRANT -o avs2yuv.exe.spec.o avs2yuv.exe.spec.c g++ -shared -Wl,-Bsymbolic -o avs2yuv.exe.so avs2yuv.o avs2yuv.exe.dbg.o avs2yuv.exe.spec.o -L/opt/wine//lib -lwine -lwine_unicode -lwine_uuid -lm test -f avs2yuv || install ./wineapploader avs2yuv
I attached the zip file with the source and any files I thought were relevant. If required I can send additional files dll's in a private email (such as the required dll's).
Wine version 20031212 built from source on a RedHat System. I had the exact same problem when I used the debs from unstable (also version 20031212) on a libranet system.
Is this a bug, or am I doing something wrong?
When I used a a version of avisynth_c.dll which used cdecl on all API functions -- without changing the .def or header files -- instead of stdlib I do not have this problem. Naturally I do not expect it to run since I didn't recompile my code with the proper header files. I discovered this by accident because the previous version used cdecl and I had some old dll laying around in a place wine was able to find.
Can anyone help me get this working? Am I doing something wrong or is this a bug in wine?
Thanks in advance.
LIBRARY avisynth_c.dll
EXPORTS
AvisynthPluginInit2@4 @1
avs_add_function@20 @2
avs_at_exit@12 @3
avs_bit_blt@28 @4
avs_check_version@8 @5
avs_clip_get_error@4 @6
avs_copy_clip@4 @7
avs_copy_value@12 @8
avs_copy_video_frame@4 @9
avs_create_script_environment@4 @10
avs_function_exists@8 @11
avs_get_audio@24 @12
avs_get_cpu_flags@4 @13
avs_get_frame@8 @14
avs_get_parity@8 @15
avs_get_var@8 @16
avs_get_version@4 @17
avs_get_video_info@4 @18
avs_invoke@20 @19
avs_make_writable@8 @20
avs_new_c_filter@20 @21
avs_new_video_frame_a@12 @22
avs_release_clip@4 @23
avs_release_value@8 @24
avs_release_video_frame@4 @25
avs_save_string@12 @26
avs_set_cache_hints@12 @27
avs_set_global_var@16 @28
avs_set_memory_max@8 @29
avs_set_to_clip@8 @30
avs_set_var@16 @31
avs_set_working_dir@8 @32
avs_subframe@24 @34
avs_take_clip@12 @35
avs_vsprintf@12 @36
avs_sprintf @33
On Mon, 22 Dec 2003, Boaz Harrosh wrote:
I have stdcall working fine here.
There is something wrong with your DLL the fact that "pexports" dumped "_" before symbol names is a clue to those functions been exported as cdecl. In stdcall (or PASCAL) no under-scored is perpended. (and you should see the @number at end of names). check to see how this DLL was compiled on windows (or wine). Was it compiled with a .DEF file?
The DLL was compiled with Visual C++ without the .def file. Um, if it is cdecl why is the @ at the end of the names. The DLL works just fine when linked with a mingw compiled executable.
Recombining the DLL with gcc is NOT an option.
On Mon, 22 Dec 2003, Kevin Atkinson wrote:
On Mon, 22 Dec 2003, Boaz Harrosh wrote:
I have stdcall working fine here.
There is something wrong with your DLL the fact that "pexports" dumped "_" before symbol names is a clue to those functions been exported as cdecl. In stdcall (or PASCAL) no under-scored is perpended. (and you should see the @number at end of names). check to see how this DLL was compiled on windows (or wine). Was it compiled with a .DEF file?
The DLL was compiled with Visual C++ without the .def file. Um, if it is cdecl why is the @ at the end of the names. The DLL works just fine when linked with a mingw compiled executable.
Also, when I make it cdecl there is NO underscore.
Recombining the DLL with gcc is NOT an option.
Kevin is right on all accounts. I can reproduce his problems here. If I go to the foo.spec.c file produced by winebuild for the user application and manually change, at the big "import" structure, all the stdcall functions than it works. An example is do.
What was produced by winebuild: <original foo.dll.spec.c>
static struct { struct { void *OriginalFirstThunk; unsigned int TimeDateStamp; unsigned int ForwarderChain; const char *Name; void *FirstThunk; } imp[11]; const char *data[109]; } imports = { { ..... /* foo.dll */ "\001\000fnFooC", "\002\000fnFooSTD", 0, .... </original foo.dll.spec.c>
change to :
<fixed foo.dll.spec.c> ..... /* foo.dll */ "\001\000fnFooC", "\002\000_fnFooSTD@8", 0, .... </fixed foo.dll.spec.c>
than compilation and runtime succeeds. So the fault is at winebuild (when doing the Import, since the .def file had it right) . Or is there a switch missing?
If I understood correctly the process that is done on windows. Than all the searching and converting of Names is done by the VC linker. Hence the fix should be done at winebuild. In windows an: " int __stdcall fnFooSTD(long ,long) declaration linked against an import-lib of a DLL. Will look and successfully link both fnFooSTD (in-case a .DEF file was used in compilation of the DLL) or _fnFooSTD@8. (Needless to say that an ordinal will replace a name if Flagged by the import-lib). winebuild successfully understood that an _fnFooSTD@8 should make an fnFooSTD symbol for GCC (at the "asm(".data\n) section) but forgot to keep the real _fnFooSTD@8 name for the import-table. Any one with a quick hand at the winebuild?
I have at hand the most simple dll compiled by VC6 (+sources) and the winelib app any one wants to have a look? Please forgive me if this was already fixed since I have an old Wine (2 month old)
Free Life Boaz
Kevin Atkinson wrote:
On Mon, 22 Dec 2003, Kevin Atkinson wrote:
On Mon, 22 Dec 2003, Boaz Harrosh wrote:
I have stdcall working fine here.
There is something wrong with your DLL the fact that "pexports" dumped "_" before symbol names is a clue to those functions been exported as cdecl. In stdcall (or PASCAL) no under-scored is perpended. (and you should see the @number at end of names). check to see how this DLL was compiled on windows (or wine). Was it compiled with a .DEF file?
The DLL was compiled with Visual C++ without the .def file. Um, if it is cdecl why is the @ at the end of the names. The DLL works just fine when linked with a mingw compiled executable.
Also, when I make it cdecl there is NO underscore.
Recombining the DLL with gcc is NOT an option.
"Boaz Harrosh" boaz@hishome.net wrote:
} imports = { { ..... /* foo.dll */ "\001\000fnFooC", "\002\000fnFooSTD", 0, .... </original foo.dll.spec.c>
change to :
<fixed foo.dll.spec.c> ..... /* foo.dll */ "\001\000fnFooC", "\002\000_fnFooSTD@8", 0, .... </fixed foo.dll.spec.c>
than compilation and runtime succeeds. So the fault is at winebuild (when doing the Import, since the .def file had it right) . Or is there a switch missing?
No, that's not a winebuild problem. You have fixed names directly in the imports, that means that your dll is broken, i.e. it has decorated (@xx) API names in the exports.
I have at hand the most simple dll compiled by VC6 (+sources) and the winelib app any one wants to have a look?
Yes, please send it here if it really small, otherwise send it to me directly. (Comress with 'bzip -9' before sending).
Dmitry Timoshkov wrote:
"Boaz Harrosh" boaz@hishome.net wrote:
} imports = { { ..... /* foo.dll */ "\001\000fnFooC", "\002\000fnFooSTD", 0, .... </original foo.dll.spec.c>
change to :
<fixed foo.dll.spec.c> ..... /* foo.dll */ "\001\000fnFooC", "\002\000_fnFooSTD@8", 0, .... </fixed foo.dll.spec.c>
than compilation and runtime succeeds. So the fault is at winebuild (when doing the Import, since the .def file had it right) . Or is there a switch missing?
No, that's not a winebuild problem. You have fixed names directly in the imports, that means that your dll is broken, i.e. it has decorated (@xx) API names in the exports.
I have at hand the most simple dll compiled by VC6 (+sources) and the winelib app any one wants to have a look?
Yes, please send it here if it really small, otherwise send it to me directly. (Comress with 'bzip -9' before sending).
Well yes they are decorated. This is the way the VC made them. I guess they are not Decorated only if you use a .DEF file. If you export them with __declspec(dllexport) they are exported decorated.
I hope 17K is what you mean by small. All files and Foo.dll are windows files. only fooapp.cpp & Foo.dll.spec are winelib source files. I did not send Linux makefiles, to keep it small.
Boaz
On Wed, 24 Dec 2003, Boaz Harrosh wrote:
Well yes they are decorated. This is the way the VC made them. I guess they are not Decorated only if you use a .DEF file. If you export them with __declspec(dllexport) they are exported decorated.
You are correct. If I use a .def file WITH the @ decorations that I get linker errors. If I use a .def with just the names they are exported without the @, EVEN if they are still declared with dllexport. Very strange.
"Kevin Atkinson" kevina@gnu.org wrote:
Well yes they are decorated. This is the way the VC made them. I guess they are not Decorated only if you use a .DEF file. If you export them with __declspec(dllexport) they are exported decorated.
You are correct. If I use a .def file WITH the @ decorations that I get linker errors. If I use a .def with just the names they are exported without the @, EVEN if they are still declared with dllexport. Very strange.
I'm tempted to say that it's a MS' linker bug. But I'm afraid that there are lots of applications build that way (using __declspec(dllexport)) and not a .def file.
You could try to add decorations to the stdapi exports in the .spec file in order to workaround that. Or even add the decoration twice. You have to try it actually and look at the generated .spec.c file to see what happens in reality.
On Wed, 24 Dec 2003, Dmitry Timoshkov wrote:
"Kevin Atkinson" kevina@gnu.org wrote:
Well yes they are decorated. This is the way the VC made them. I guess they are not Decorated only if you use a .DEF file. If you export them with __declspec(dllexport) they are exported decorated.
You are correct. If I use a .def file WITH the @ decorations that I get linker errors. If I use a .def with just the names they are exported without the @, EVEN if they are still declared with dllexport. Very strange.
I'm tempted to say that it's a MS' linker bug. But I'm afraid that there are lots of applications build that way (using __declspec(dllexport)) and not a .def file.
You could try to add decorations to the stdapi exports in the .spec file in order to workaround that. Or even add the decoration twice. You have to try it actually and look at the generated .spec.c file to see what happens in reality.
So are you saying that it is not possible to fix winbuild to deal with DLL witch only use __declspec(dllexport) to export their functions?
"Kevin Atkinson" kevina@gnu.org wrote:
So are you saying that it is not possible to fix winbuild to deal with DLL witch only use __declspec(dllexport) to export their functions?
How would you imagine that fix? A .spec file is generated by you and not by winebuild. Just place the correct API names there (i.e. real names from the export table of your dll, what ever they are).
On Wed, 24 Dec 2003, Dmitry Timoshkov wrote:
"Kevin Atkinson" kevina@gnu.org wrote:
So are you saying that it is not possible to fix winbuild to deal with DLL witch only use __declspec(dllexport) to export their functions?
How would you imagine that fix? A .spec file is generated by you and not by winebuild. Just place the correct API names there (i.e. real names from the export table of your dll, what ever they are).
How about being able to use the the .lib file like mingw does?
"Kevin Atkinson" kevina@gnu.org wrote:
How about being able to use the the .lib file like mingw does?
If you will contribute such a patch for winebuild I think it will be accepted.
Kevin Atkinson wrote:
On Wed, 24 Dec 2003, Dmitry Timoshkov wrote:
"Kevin Atkinson" kevina@gnu.org wrote:
Well yes they are decorated. This is the way the VC made them. I guess they are not Decorated only if you use a .DEF file. If you export them with __declspec(dllexport) they are exported decorated.
You are correct. If I use a .def file WITH the @ decorations that I get linker errors. If I use a .def with just the names they are exported without the @, EVEN if they are still declared with dllexport. Very strange.
I'm tempted to say that it's a MS' linker bug. But I'm afraid that there are lots of applications build that way (using __declspec(dllexport)) and not a .def file.
You could try to add decorations to the stdapi exports in the .spec file in order to workaround that. Or even add the decoration twice. You have to try it actually and look at the generated .spec.c file to see what happens in reality.
So are you saying that it is not possible to fix winbuild to deal with DLL witch only use __declspec(dllexport) to export their functions?
I tried Dmitry's solution but it does not work.
If I put at my foo.dll.spec : @ stdcall fnFooSTD(long long) _fnFooSTD@8
I get at my libFoo.def : fnFooSTD@8=_fnFooSTD@8@8 @2 And at my app.exe.spec.c I still get fnFooSTD in my Import table
If I manually change libFoo.def to: fnFooSTD@8=_fnFooSTD@8 @2 I still get fnFooSTD in my Import table
If I do @ stdcall fnFooSTD@8(long long) I get at libFoo.def a: fnFooSTD@8 @2 And I still get fnFooSTD in my Import table
And even if I do: @ cdecl fnFooSTD(long long) _fnFooSTD@8 I get my fnFooSTD=_fnFooSTD@8 @2 And I still get fnFooSTD in my Import table
So currently the only way to get it right ( That I found. I will be happy for suggestions) Is to: 1) manually patch the app.exe.spec.c after it was Generated
I would like to summarize: in an stdcall functions generated by MSVC++ export directive, One needs a none-decorated name in his asm.data section to satisfy the GCC linker. and a Decorated name in the Import table to satisfy the Loader. Currently there is no way to do it Automatically.
[Q] If we are at it can we get rid of the libFoo.def file all together and link directly with Foo.dll.spec file. It looks like a much easier system to maintain. I recall a discussion about it but can't remember what was said. I understand, Historical reason, but it looks silly that I have to invoke WINEBUILD to read in a .SPEC file and write a .DEF file and then invoke it once again to read in a .DEF file. It sounds like this old, "One Policeman can read One Policeman can write" Joke. No offense intended. I do understand, History.
"Boaz Harrosh" boaz@hishome.net wrote:
I tried Dmitry's solution but it does not work.
You have to put approximately following in the .spec file to make it work:
foo.dll.spec : @ stdcall fnFooSTD@8(long long) _fnFooSTD@8
or try do add @8 twice on one/both of the sides. That's a pure speculation on my side, you have to try it on your own and experiment a bit.
I did, I have tried both your suggestions.
What ever you do. any thing after the @ sign gets truncated in the import process and will not Reach the Import table.
Note that in any way we need a split. asm(.data section) needs a none-decorated name and the Import table needs a Decorated one. What ever you do to winebuild it will not write two separate names. right?
Or maybe it is my 2-month old wine? was that fixed lately?
Dmitry Timoshkov wrote:
"Boaz Harrosh" boaz@hishome.net wrote:
I tried Dmitry's solution but it does not work.
You have to put approximately following in the .spec file to make it work:
foo.dll.spec : @ stdcall fnFooSTD@8(long long) _fnFooSTD@8
or try do add @8 twice on one/both of the sides. That's a pure speculation on my side, you have to try it on your own and experiment a bit.
"Boaz Harrosh" boaz@hishome.net wrote:
I did, I have tried both your suggestions.
What ever you do. any thing after the @ sign gets truncated in the import process and will not Reach the Import table.
Note that in any way we need a split. asm(.data section) needs a none-decorated name and the Import table needs a Decorated one. What ever you do to winebuild it will not write two separate names. right?
I don't know what exactly you did try, but here is my results, based on your code:
Foo.spec:
@ stdcall fnFooSTD@8@8(long long) fnFooSTD @ cdecl fnFooC (long long) fnFooC
resulted Foo.spec.c:
asm(".data\n" "\t.align 4\n" "__wine_spec_exports:\n" "\t.long 0\n" "\t.long 0\n" "\t.long 0\n" "\t.long __wine_spec_exp_names\n" "\t.long 1\n" "\t.long 2\n" "\t.long 2\n" "\t.long __wine_spec_exports_funcs\n" "\t.long __wine_spec_exp_name_ptrs\n" "\t.long __wine_spec_exp_ordinals\n" "__wine_spec_exports_funcs:\n" "\t.long fnFooC\n" "\t.long fnFooSTD\n" "__wine_spec_exp_name_ptrs:\n" "\t.long __wine_spec_exp_names+8\n" "\t.long __wine_spec_exp_names+15\n" "\t.text\n" "__wine_spec_exp_names:\n" "\t.string "Foo.dll"\n" "\t.string "fnFooC"\n" "\t.string "fnFooSTD@8"\n" ^^^^^^^^^^<----------------------------<<<<<<<<< "\t.data\n" "__wine_spec_exp_ordinals:\n" "\t.short 0\n" "\t.short 1\n" "\tjmp fnFooC\n" "\tret\n" "\t.short 8\n" "\t.long fnFooC,0x00000000\n" "\tjmp fnFooSTD\n" "\tret $8\n" "\t.long fnFooSTD,0x00000000\n" "\t.text\n" "\t.align 4\n" );
As you can see it works for me.
On Thu, 25 Dec 2003, Dmitry Timoshkov wrote:
"Boaz Harrosh" boaz@hishome.net wrote:
I did, I have tried both your suggestions.
What ever you do. any thing after the @ sign gets truncated in the import process and will not Reach the Import table.
Note that in any way we need a split. asm(.data section) needs a none-decorated name and the Import table needs a Decorated one. What ever you do to winebuild it will not write two separate names. right?
I don't know what exactly you did try, but here is my results, based on your code:
Foo.spec:
@ stdcall fnFooSTD@8@8(long long) fnFooSTD @ cdecl fnFooC (long long) fnFooC
That is a heck of a lot of work to link with a DLL that is not compiled with an exports table.
Furthermore, when I use an exports table (ie compile with /def in VC++) mingw has problems linking with the DLL. It could be that I need to pass in special options. Simply including the ".lib" file as a link object is not enough.
It seams rather strange that wine has so much problems linking with a DLL not compiled with an exports table. Am I the first one who attempted this.
"Kevin Atkinson" kevina@gnu.org wrote:
That is a heck of a lot of work to link with a DLL that is not compiled with an exports table.
I don't understand you. If a DLL exports something (i.e. has a not zero export directory in the PE header), then it definitely has an export table.
Furthermore, when I use an exports table (ie compile with /def in VC++) mingw has problems linking with the DLL. It could be that I need to pass in special options. Simply including the ".lib" file as a link object is not enough.
MinGW (or rather Windows ld port) has its own heuristics for resolving symbols in external libraries. So, just stick to rules and read its documentation. I have an old dllhelpers-0.2.6.tar.gz addon for MinGW with samples how to use DLLs with MinGW, you could find something similar on the net.
I'd say that the key of your problems is a bug in MS linker which exports decorated API names. That's similar to an attempt to link against a DLL with C++ style decorated exports created by a compiler from another vendor.
It seams rather strange that wine has so much problems linking with a DLL not compiled with an exports table. Am I the first one who attempted this.
Probably. Don't forget: Wine is alpha software. Every your contribution makes it better, as it has become much better with the help of many other people.
On Fri, 26 Dec 2003, Dmitry Timoshkov wrote:
"Kevin Atkinson" kevina@gnu.org wrote:
That is a heck of a lot of work to link with a DLL that is not compiled with an exports table.
I don't understand you. If a DLL exports something (i.e. has a not zero export directory in the PE header), then it definitely has an export table.
Sorry. I mean what it is compiled with a .def file rather than using __declspec(dllexport).
Furthermore, when I use an exports table (ie compile with /def in VC++) mingw has problems linking with the DLL. It could be that I need to pass in special options. Simply including the ".lib" file as a link object is not enough.
MinGW (or rather Windows ld port) has its own heuristics for resolving symbols in external libraries. So, just stick to rules and read its documentation. I have an old dllhelpers-0.2.6.tar.gz addon for MinGW with samples how to use DLLs with MinGW, you could find something similar on the net.
I'd say that the key of your problems is a bug in MS linker which exports decorated API names. That's similar to an attempt to link against a DLL with C++ style decorated exports created by a compiler from another vendor.
If the names are not decorated in that fashion mingw has a problem linking with it. When linked the linker is looking for the names with the '@' decoration.
I would hardly call the '@' decoration a bug, it is the way it is done in windows. It is spelled out in the documentation that way.
It seams rather strange that wine has so much problems linking with a DLL not compiled with an exports table. Am I the first one who attempted this.
Probably. Don't forget: Wine is alpha software. Every your contribution makes it better, as it has become much better with the help of many other people.
Yeah, yeah. I don't know the least thing about windows linking or how to fix wine to make it handle this situation better. So I guess if I don't contribute a patch to handle this it won't get fixed anytime soon.
"Kevin Atkinson" kevina@gnu.org wrote:
If the names are not decorated in that fashion mingw has a problem linking with it. When linked the linker is looking for the names with the '@' decoration.
... in the object files. That's a way compilers treat __stdcall keyword in the windows world.
I would hardly call the '@' decoration a bug, it is the way it is done in windows. It is spelled out in the documentation that way.
That's a misunderstanding. Symbols get decorated only in object files, linker strips them out and a final PE binary should not have that crap. All standard windows dlls have no '@' character in the exported APIs.
However as you have discovered MS linker does not always strip the stdcall decorations. That does not affect the things under Windows if both .exe and .dll were created by the same (buggy) tool chain. But in the case of mixing build environments you have a lot of troubles.
On Fri, 26 Dec 2003, Dmitry Timoshkov wrote:
"Kevin Atkinson" kevina@gnu.org wrote:
If the names are not decorated in that fashion mingw has a problem linking with it. When linked the linker is looking for the names with the '@' decoration.
... in the object files. That's a way compilers treat __stdcall keyword in the windows world.
But also when I link with the DLL. When I attempt to link I get this:
gcc -O -Wall -shared examples.o avisynth_c.lib -o examples.dll examples.o(.text+0x33):examples.c: undefined reference to `avs_new_c_filter@20' examples.o(.text+0x41):examples.c: undefined reference to `avs_set_to_clip@8'
With the __declspec(dllimport):
gcc -O -Wall -shared examples.o avisynth_c.lib -o examples.dll examples.o(.text+0x34):examples.c: undefined reference to `_imp__avs_new_c_filter@20' examples.o(.text+0x43):examples.c: undefined reference to `_imp__avs_set_to_clip@8'
So without special treatment mingw gcc seams to also expect the @ decoration.
I don't care if you consider it a "bug". I am just reporting how it is done. And the fact that it is causing me a lot of grief.
Dmitry Timoshkov wrote:
Foo.spec:
@ stdcall fnFooSTD@8@8(long long) fnFooSTD @ cdecl fnFooC (long long) fnFooC
resulted Foo.spec.c:
asm(".data\n" "\t.align 4\n" "__wine_spec_exports:\n" "\t.long 0\n" "\t.long 0\n" "\t.long 0\n" "\t.long __wine_spec_exp_names\n" "\t.long 1\n" "\t.long 2\n" "\t.long 2\n" "\t.long __wine_spec_exports_funcs\n" "\t.long __wine_spec_exp_name_ptrs\n" "\t.long __wine_spec_exp_ordinals\n" "__wine_spec_exports_funcs:\n" "\t.long fnFooC\n" "\t.long fnFooSTD\n" "__wine_spec_exp_name_ptrs:\n" "\t.long __wine_spec_exp_names+8\n" "\t.long __wine_spec_exp_names+15\n" "\t.text\n" "__wine_spec_exp_names:\n" "\t.string "Foo.dll"\n" "\t.string "fnFooC"\n" "\t.string "fnFooSTD@8"\n" ^^^^^^^^^^<----------------------------<<<<<<<<< "\t.data\n" "__wine_spec_exp_ordinals:\n" "\t.short 0\n" "\t.short 1\n" "\tjmp fnFooC\n" "\tret\n" "\t.short 8\n" "\t.long fnFooC,0x00000000\n" "\tjmp fnFooSTD\n" "\tret $8\n" "\t.long fnFooSTD,0x00000000\n" "\t.text\n" "\t.align 4\n" );
As you can see it works for me.
Dear Dmitry you have been most patience with me and I already feel silly but please I am not able to reproduce your results.
1) I have put above two lines in a Foo.dll.spec file
2) Here is my command line dump: * gcc -c -I. -I/home/wine/include/wine/windows -g -fPIC -D_REENTRANT -o fooapp.o fooapp.c * LD_LIBRARY_PATH="/home/wine/lib" /home/wine/bin/winebuild -fPIC -o libFoo.def --def Foo.dll.spec * LD_LIBRARY_PATH="/home/wine/lib" /home/wine/bin/winebuild -fPIC -o fooapp.exe.spec.c --exe fooapp.exe fooapp.o -L. -lFoo -L/home/wine/lib/wine -ladvapi32 -lkernel32 -lshell32 -luser32
3) Here is my result fooapp.exe.spec.c: ....
} imports = { { { 0, 0, 0, "Foo.dll", &imports.data[0] }, { 0, 0, 0, "kernel32.dll", &imports.data[2] }, { 0, 0, 0, 0, 0 }, }, { /* Foo.dll */ "\001\000fnFooC", 0, /* kernel32.dll */ "\045\001ExitProcess", "\215\001GetCommandLineA", "\373\001GetModuleHandleA", "\056\002GetStartupInfoA", 0, } };
#ifndef __GNUC__ static void __asm__dummy_import(void) { #endif
asm(".data\n\t.align 8\n" "\t.type fnFooC,@function\n" "\t.globl fnFooC\n" "fnFooC:\n\tjmp *(imports+60)\n\tmovl %esi,%esi\n" "\t.type ExitProcess,@function\n" "\t.globl ExitProcess\n" "ExitProcess:\n\tjmp *(imports+68)\n\tmovl %esi,%esi\n" "\t.type GetCommandLineA,@function\n" "\t.globl GetCommandLineA\n" "GetCommandLineA:\n\tjmp *(imports+72)\n\tmovl %esi,%esi\n" "\t.type GetModuleHandleA,@function\n" "\t.globl GetModuleHandleA\n" "GetModuleHandleA:\n\tjmp *(imports+76)\n\tmovl %esi,%esi\n" "\t.type GetStartupInfoA,@function\n" "\t.globl GetStartupInfoA\n" "GetStartupInfoA:\n\tjmp *(imports+80)\n\tmovl %esi,%esi\n" ".text"); #ifndef __GNUC__ } #endif ....
I have noticed that my .spec.c file is very different than your .spec.c file from above. I am using winebuild downloaded from source forge, as of 20031212.
Now if I use your suggested .spec file. I am missing the FooSTD altogether. If I remove one of the @8 than I am back to my old problem.
[Q-1] Why is my .spec.c file so different than yours? could you please check my command line switches? could you please send me your makefiles (command line) that produced above results.
[Q-2] I Have mandrake 9.1, GCC 3.3.1, winebuild extracted from Wine-20031212-i386-S9nodebug-2.tgz downloaded from sourceforge. Is winebuild a simple elf program that only dependent on GLIBC? or is it using other binary files/libraries that I should check versions of? Mainly is it dependent on any other wine utility/library?
Thanks in advance. And happy holidays Boaz
"Boaz Harrosh" boaz@hishome.net wrote:
I have noticed that my .spec.c file is very different than your .spec.c file from above. I am using winebuild downloaded from source forge, as of 20031212.
Now if I use your suggested .spec file. I am missing the FooSTD altogether. If I remove one of the @8 than I am back to my old problem.
[Q-1] Why is my .spec.c file so different than yours? could you please check my command line switches? could you please send me your makefiles (command line) that produced above results.
Our spec file are different because my one is for Foo.dll, and yours is for fooapp.exe.
Anyway I'm attaching my sources and Makefiles. I simply integrated Foo.dll into Wine dll/ tree and hacked Makefiles accordingly.
And no, I didn't succeed linking with Foo.dll.so. Mainly because winebuild doesn't know how to resolve a non stdcall decorated symbol to a decorated one.
Let's wait for Alexandre and hear his opinion whether it worths the trouble adding support for linking with broken Windows DLLs.
Thanks. So I'll stay with my current hand hacked .spec.c file. It does work at least.
My be we should define a new keyword in spec files, let's say "decorated" which implies stdcall and keeps the decoration on the export/import table. I'll look into it once I finish my current doing.
Free Life Boaz
Dmitry Timoshkov wrote:
"Boaz Harrosh" boaz@hishome.net wrote:
I have noticed that my .spec.c file is very different than your .spec.c file from above. I am using winebuild downloaded from source forge, as of 20031212.
Now if I use your suggested .spec file. I am missing the FooSTD altogether. If I remove one of the @8 than I am back to my old problem.
[Q-1] Why is my .spec.c file so different than yours? could you please check my command line switches? could you please send me your makefiles (command line) that produced above results.
Our spec file are different because my one is for Foo.dll, and yours is for fooapp.exe.
Anyway I'm attaching my sources and Makefiles. I simply integrated Foo.dll into Wine dll/ tree and hacked Makefiles accordingly.
And no, I didn't succeed linking with Foo.dll.so. Mainly because winebuild doesn't know how to resolve a non stdcall decorated symbol to a decorated one.
Let's wait for Alexandre and hear his opinion whether it worths the trouble adding support for linking with broken Windows DLLs.
On December 24, 2003 11:15 am, Boaz Harrosh wrote:
If we are at it can we get rid of the libFoo.def file all together and link directly with Foo.dll.spec file. It looks like a much easier system to maintain. I recall a discussion about it but can't remember what was said.
But you are dealing just with the .spec file, the .spec -> .def file is both automatic and fast. Not a concern. But it allows our build process to be closer to the native one, which is good and quite valuable to Winelib. I see no reason to change the current setup.