From: jugg <ju...@ho...> - 2003-11-13 04:10:36
|
Hi all, I've been trying to track this down, but can not seem to come up with the correct search pattern to find previous discussion on it. (some subjects but not completely answering what I'm looking for). Sorry if I'm overly wordy, I tried to be as concise as possible and still present the needed info. So here is the deal... I'm building DLLs (some are dependent on others) and an app .exe which uses these .dlls. I come from the MSVC++ world, and so I am used to be able to do the following: When creating a dll I use this for my functions: __declspec( dllexport ) VOID __stdcall MyFunc( BOOL ){ ... } Then I specify in a .def file EXPORTS MyFunc which exposes MyFunc from the .dll instead of _MyFunc@4. When using this .dll in another .dll or app, I simply use this declaration and link against the library generated for it: __declspec( dllimport ) VOID __stdcall MyFunc( BOOL ); Ok so there are several problems (possibly related) that I have come upon when trying to use this method in MinGW. The first problem I run into is that I can not link against the import library that is generated from the .dll, because the linker looks for _imp__MyFunc@4. If I don't specify the __declspec( dllimport ) on the function declaration, then it still doesn't work, because the linker looks for _MyFunc@4 and fails again for some reason. (The function is exposed as MyFunc from the .dll). The basic command line I used for this is what is at http://www.mingw.org/docs.shtml under the building .dlls section with the addition of specifying a .def file for cleaning up the functions. I've tried using --enable-auto-import to no avail (maybe it isn't meant to help with this issue?) The second problem I have when using MinGW is if a function is not in the .def file it is not exported, even though I use __declspec( dllexport ) on the function. This is a problem to me, because I only put __stdcall functions into the .def file, and __cdecl functions I leave out of the .def file as they are already "clean". From what I have read, if you use a .def file, then the default --export-all-symbols is ignored, and only what is in the .def is exported. But, if I specifically specify --export-all-symbols on the command line, I would have thought it would still export all declared exports in the code. Perhaps I'm confused again on the purpose of that parameter. I just find it really annoying to have to specify all of my exports in the def file, which makes it a bear to maintain (keeping it and the headers synced). This wouldn't be such a big issue, except for the fact that the program isn't all self-contained. It uses a lot of 3rd party plugins, many of which use GetProcAddress for various exported functions. So it isn't a simple issue of updating only the core code to use whatever function exports I can make MinGW give me. The .dlls need to have the same interface as if they were generated by MSVC. Anyway, the following is the only way I have found that gives me most of what I want (thanks to the morons guide located at http://www.emmestech.com/software/cygwin/pexports-0.43/moron2.html) I have to create an "exports.def" file and an "imports.def" file. Both files contain all of the functions in the .dll. The "exports.def" file contain "clean" function names, without any underscores or @xx. ie MyFunc. The "imports.def" file has all of the functions listed raw. ie MyFunc@4. I then use the following command line to build my code: gcc -c -DBUILD_DLL -D_NDEBUG ./myapi.c gcc --disable-stdcall-fixup -mdll -DBUILD_DLL \ -o junk.tmp -Wl,--base-file,base.tmp ./myapi.o rm junk.tmp dlltool --dllname myapi.dll --base-file base.tmp \ --output-exp temp.exp --input-def exports.def rm base.tmp gcc --enable-stdcall-fixup -mdll -DBUILD_DLL \ -o myapi.dll ./myapi.o -Wl,temp.exp rm temp.exp dlltool --input-def imports.def --dllname myapi.dll \ --output-lib libmyapi.a -k This creates myapi.dll and the final libmyapi.a is a usable library that I can link against. I am really hoping that I have made this process way too complicated, and there is a simple way to produce the .dll and library I need. But as it is right now it just seems to be a bit too much, and I'm not fully confident that everything will behave. One last issue is that I have a couple of __stdcall functions that were implemented a long time ago and never stripped of their underscore and @xx stuff, and so I must keep them as such for compatibility issues. Using my method above, I have not figured out how to keep these functions unmodified while the rest of the functions get cleaned up (because everything must be specified in the .def file that I want exported). The sticky part coming in where they need to have an underscore in front. (I can get the @xx to be added by simply modifying the exports.def file to include it as well as the imports.def). If this has all been discussed and figured out before, I'll appreciate a pointer to the reference, and by much appreciative. Otherwise, I'll try to answer any questions and clarify things if needed. Here is to hoping I can use gcc/mingw full time soon... chris |
From: Luke D. <cod...@ho...> - 2003-11-21 02:02:36
|
----- Original Message ----- From: "jugg" <ju...@ho...> To: <min...@li...> Sent: Thursday, November 13, 2003 12:10 PM Subject: [Mingw-users] dll export/import issues [snip] > I come from the MSVC++ world, and so I am used to be able to do the > following: > > When creating a dll I use this for my functions: > > __declspec( dllexport ) VOID __stdcall MyFunc( BOOL ){ ... } > > Then I specify in a .def file > EXPORTS > MyFunc > > which exposes MyFunc from the .dll instead of _MyFunc@4. As you have found, it isn't quite that simple with MinGW GCC. Have you seen this page?: http://mywebpage.netscape.com/yongweiwu/stdcall.htm > When using this .dll in another .dll or app, I simply use this > declaration and link against the library generated for it: > > __declspec( dllimport ) VOID __stdcall MyFunc( BOOL ); > > Ok so there are several problems (possibly related) that I have come > upon when trying to use this method in MinGW. > > The first problem I run into is that I can not link against the import > library that is generated from the .dll, because the linker looks for > _imp__MyFunc@4. If I don't specify the __declspec( dllimport ) on the > function declaration, then it still doesn't work, because the linker > looks for _MyFunc@4 and fails again for some reason. (The function is > exposed as MyFunc from the .dll). Is this with the import library generated by MSVC or by MinGW, and I assume you are linking it using GCC? > The basic command line I used for this is what is at > http://www.mingw.org/docs.shtml under the building .dlls section with > the addition of specifying a .def file for cleaning up the functions. > I've tried using --enable-auto-import to no avail (maybe it isn't meant > to help with this issue?) No, the auto-import features are used when building the modules that use the DLL, and they are only used to allow linking without __declspec(dllimport). > The second problem I have when using MinGW is if a function is not in > the .def file it is not exported, even though I use __declspec( > dllexport ) on the function. This is a problem to me, because I only > put __stdcall functions into the .def file, and __cdecl functions I > leave out of the .def file as they are already "clean". I guess it was never intended that you could use a mixture of dllexport and .def files with MinGW, but maybe it's still a bug. > From what I have read, if you use a .def file, then the default > --export-all-symbols is ignored, and only what is in the .def is > exported. But, if I specifically specify --export-all-symbols on the > command line, I would have thought it would still export all declared > exports in the code. Perhaps I'm confused again on the purpose of that > parameter. I just find it really annoying to have to specify all of my > exports in the def file, which makes it a bear to maintain (keeping it > and the headers synced). The --export-all-symbols option is really intended for when you use neither dllexport nor a .def file, to cause every global symbol to be exported. > This wouldn't be such a big issue, except for the fact that the program > isn't all self-contained. It uses a lot of 3rd party plugins, many of > which use GetProcAddress for various exported functions. So it isn't a > simple issue of updating only the core code to use whatever function > exports I can make MinGW give me. The .dlls need to have the same > interface as if they were generated by MSVC. This requirement is of course where it gets difficult because IMHO the way these DLL features were added to binutils/gcc seems to have been incremental and a bit arbitrary, probably because there is no good MS documentation describing precisely how it all works (e.g. mixing dllexport with a .def file, or what cases cause decorated stdcall names). The way .def files work with MSVC seems strange to me to begin with. Have you tried the --add-stdcall-alias linker option? > Anyway, the following is the only way I have found that gives me most of > what I want (thanks to the morons guide located at > http://www.emmestech.com/software/cygwin/pexports-0.43/moron2.html) > > I have to create an "exports.def" file and an "imports.def" file. Both > files contain all of the functions in the .dll. The "exports.def" file > contain "clean" function names, without any underscores or @xx. ie > MyFunc. The "imports.def" file has all of the functions listed raw. ie > MyFunc@4. > > I then use the following command line to build my code: > > gcc -c -DBUILD_DLL -D_NDEBUG ./myapi.c > gcc --disable-stdcall-fixup -mdll -DBUILD_DLL \ > -o junk.tmp -Wl,--base-file,base.tmp ./myapi.o > rm junk.tmp > dlltool --dllname myapi.dll --base-file base.tmp \ > --output-exp temp.exp --input-def exports.def > rm base.tmp > gcc --enable-stdcall-fixup -mdll -DBUILD_DLL \ > -o myapi.dll ./myapi.o -Wl,temp.exp > rm temp.exp > dlltool --input-def imports.def --dllname myapi.dll \ > --output-lib libmyapi.a -k > > This creates myapi.dll and the final libmyapi.a is a usable library that > I can link against. > > I am really hoping that I have made this process way too complicated, > and there is a simple way to produce the .dll and library I need. But as > it is right now it just seems to be a bit too much, and I'm not fully > confident that everything will behave. It does sound complicated, and using "--enable-stdcall-fixup" seems a bit hackish (if it is required), but I believe the standard single-command way of building a DLL & import library may work if all components are built using MinGW but not if it is required to exactly imitate MSVC. > One last issue is that I have a couple of __stdcall functions that were > implemented a long time ago and never stripped of their underscore and > @xx stuff, and so I must keep them as such for compatibility issues. > Using my method above, I have not figured out how to keep these > functions unmodified while the rest of the functions get cleaned up > (because everything must be specified in the .def file that I want > exported). The sticky part coming in where they need to have an > underscore in front. (I can get the @xx to be added by simply modifying > the exports.def file to include it as well as the imports.def). Can you give an example of this problem? > If this has all been discussed and figured out before, I'll appreciate a > pointer to the reference, and by much appreciative. > > Otherwise, I'll try to answer any questions and clarify things if needed. > > Here is to hoping I can use gcc/mingw full time soon... > > chris Luke |