Stefan Bellon wrote:
> > Then link the DLL with libfoo.a.
> Ok, I see. However, this doesn't work if the foo.exe itself depends on
> the DLL. So, circular dependencies are impossible, correct?
Actually it's the other way around. If the .exe does not import from
the .dll (like for example, the .dll is a plug-in of some sort and is
dynamically loaded at runtime) then you can just link the .exe normally
and use -Wl,-out-implib,libfoo.a during link to just create the import
library for the .exe without the need to create a .def file.
It's only in the case that there is a circular dependency at link-time
that you have to create the .def file. So you create the import library
for the .exe, then you link the .dll against that import library (and
use -Wl,-out-implib to generate the import library for the .dll) and
then you link the .exe using the .dll's import library.
The key point here, as pointed out in the earlier reply, is that if you
do this the name of the .exe is hard-coded into the .dll, and so the
.dll ceases to be a general purpose library and can only ever be used
with that .exe. This is analogous to saying that when you link an .exe
that imports from a given .dll, it hard-codes the name of that .dll into
the .exe, which will refuse to run if the .dll cannot be located. But
that's the behavior everyone expects, not so much the reverse.
For this reason it's somewhat considered bad design on Windows to import
from the .exe in a .dll. It will work, but it's not a very pretty
situation. The way it's supposed to work is that you factor out
everything in the .exe that needs to be accessed from both the .exe and
from the .dll, and make that into its own .dll. Then both the .exe and
the original .dll import from this .dll. Or, do run-time linking
> > 2) Look up the symbol at runtime. Read up on GetProcAddress() and
> > GetModuleHandle().
> And how would I link the DLL itself using this second approach?
If you use GetProcAddress then you are doing run-time (sometimes called
dynamic) linking - the analogy to dlopen()/dlsym() on *nix. This means
that all calls to imported routines go through function pointers and
there are no symbols to resolve at link-time, because the linker has no
knowledge of what you're doing. Example (without any error checking):
int (*funcpointer) (void);
HMODULE hm = LoadLibrary ("foo.dll");
funcpointer = GetProcAddress (hm, "some_func");
int result = funcpointer ();
In this example the linker has no idea that you are importing
some_func() from foo.dll, so there is no need for an import library or
even for foo.dll to exist.
In the case of importing from an .exe, you don't need to use
LoadLibrary() since the .exe is already loaded, and the HMODULE has to
be that of the .exe, which you get from GetModuleHandle (NULL). [I