Code::Blocks

User forums => Using Code::Blocks => Topic started by: geoff1 on March 22, 2008, 11:43:34 pm

Title: Yet Another DLL question
Post by: geoff1 on March 22, 2008, 11:43:34 pm
Hi!  I'm a noobie at Code Blocks and extremely green with regard to Windows - and especially DLLs.

Here's the situation.  I have the latest CodeBlocks, and mingw/cygwin.  I have developed an application using wxWidgets and now wish to change it into a DLL.  But it calls another DLL - FSUIPC.dll which is an interface to Microbrain's Flight Simulator.  I have the FSUIPC.dll and the include file which work perfectly well in my app.

Doing some (what I consider to be horrible) mangling, I've gotten the compiler to accept the function calls to the DLL without complaining (ie by typedefing the functions and using LoadLibrary).  However, for the life of me I cannot seem to get the DLL's variables to "link" properly.

Here's what I've done: (Note that the calling program is a C++ program)
This is the original code as supplied in .h file by the author:

extern "C" {
// Globals accessible from main code
extern DWORD FSUIPC_Version;   // HIWORD is 1000 x Version Number, minimum 1998
};


While this works for the App using gcc in mingw, CodeBlocks complains at the linking stage that "undefined reference to FSUIPC_Version ".


OK, so I then have tried this:

extern __declspec(dllimport) DWORD FSUIPC_Version;

which also fails to satisfy the linker.  Note that this gives the result:
undefined reference to __imp__FSUIPC_Version


I cannot make a .lib file out of the DLL - apparently when the dll was made it was stripped.  The author trying to protect his work, I suppose - since the dll is payware.

Apparently, I cannot link directly to the DLL - using the project options and then inserting the dll does nothing.  Am I missing a linker option?  what could be the problem?  I have scoured the internet and this board so if you can point me to a solution (or outright tell me what I might have done wrong) I would greatly appreciate it.

Title: Re: Yet Another DLL question
Post by: TDragon on March 23, 2008, 02:12:35 am
Note: This question is not technically related to Code::Blocks. For future questions like this, you should look elsewhere.

I cannot make a .lib file out of the DLL - apparently when the dll was made it was stripped.
This is the key. (The GCC compiler uses .a files for import libraries rather than .lib files, but it's the same idea.)

What you need to do is create your own import library for that DLL, which you can then use in linking your program or DLL. You'll do this with a handcrafted import/export definitions file and the "dlltool" program. Going by your posted code, you should have a file "FSUIPC.def" containing the following:
Code: [Select]
LIBRARY FSUIPC.dll
EXPORTS
FSUIPC_Version DATA
Then, from the command prompt, do:
Code: [Select]
dlltool -d FSUIPC.def -l libFSUIPC.dll.a
This creates the import library "libFSUIPC.dll.a", which should then resolve your undefined reference errors (add "-lFSUIPC" to the command line -- or, in Code::Blocks, just add "FSUIPC" in the link libraries list). It is correct for you to add __declspec(dllimport) to the definition in the header file.

Note that you can import functions with a .def file as well, to avoid your "horrible mangling" and LoadLibrary calls. See this page in the MinGWiki (http://www.mingw.org/MinGWiki/index.php/CreateImportLibraries), as well as the MSDN documentation on .def files -- particularly this page (http://msdn2.microsoft.com/en-us/library/hyx1zcd3(VS.80).aspx), as you can use the entryname=internalname syntax to mix'n'match mangled names.

Cheers,
John E. / TDM
Title: Re: Yet Another DLL question
Post by: geoff1 on March 23, 2008, 03:10:19 am
Ah, so that is what a .def file is.  I couldn't make that either - at least automatically. 

Thank you so much.  I will make my own def file and follow your advice.  Fantastic.  Will post when I've got it working.

Lots to do tomorrow!   :D
Title: Re: Yet Another DLL question
Post by: severach on April 05, 2008, 11:47:00 pm
If you bring in your imports via a LIB file then that DLL must exist or your program will not start. This is fine for any DLL that is always expected to exist such as system DLLs. If you want your program to run even if the DLL doesn't exist you'll need to use LoadLibrary() and GetProcAddress(). If you only have a few functions to import you will find LoadLibrary() and GetProcAddress() easier to use.