This is probably a basic question:

//#########################################################################

// testdll.cpp

// extern function used in dll, defined in an external static library
extern int external_function();


extern __declspec(dllexport) int dll_function() {
return external_function();
}


//#########################################################################


When linking I do NOT specify the static library in which
"external_function" exists in.

This causes a linker error "extern int external_function()" unresolved
external.

The question is, do all external references in a DLL have to be resolved at
link time?

Using the above code (without the DLL spec) I can create a static library
that has an "undefined extern" that will be resolved when the exe is built.

Is this a requirement of a DLL, are there any references?

Thank you,

A.N

Re: DLL and external references by Victor

Victor
Thu Jul 15 13:31:00 CDT 2004

alias.name wrote:
> This is probably a basic question:
>
> //#########################################################################
>
> // testdll.cpp
>
> // extern function used in dll, defined in an external static library
> extern int external_function();
>
>
> extern __declspec(dllexport) int dll_function() {
> return external_function();
> }
>
>
> //#########################################################################
>
>
> When linking I do NOT specify the static library in which
> "external_function" exists in.
>
> This causes a linker error "extern int external_function()" unresolved
> external.
>
> The question is, do all external references in a DLL have to be resolved at
> link time?

Yes. In case 'external_function' is pulled from a DLL, you still
need to supply the "import lib" for that DLL, which records where
in that DLL the function is (name or ordinal number), and what DLL
to load for the EXE.

>
> Using the above code (without the DLL spec) I can create a static library
> that has an "undefined extern" that will be resolved when the exe is built.
>
> Is this a requirement of a DLL, are there any references?

Not sure I understand this question. An EXE is essentially a DLL.
So, when a DLL is built, all external references need to be resolved.
If the function uses static binding (comes from a static library),
the library has to be supplied at the time of linking. If the symbol
(function) uses dynamic binding (comes from a DLL), the _import_
library needs to be supplied at the time of linking.

Basically, there is no difference in linking a DLL or an EXE. The
latter doesn't produce the import lib (usually), and has a different
file extension. The inner format and ways to resolve symbols are
essentially the same.

Victor

Re: DLL and external references by William

William
Thu Jul 15 13:46:59 CDT 2004

"alias.name" <alias.name@gmail.com> wrote in message
news:Xns9527735735581aliasnamegmailcom@207.217.125.205...
> This is probably a basic question:

It is.

> When linking I do NOT specify the static library in which
> "external_function" exists in.
>
> This causes a linker error "extern int external_function()" unresolved
> external.
>
> The question is, do all external references in a DLL have to be resolved
at
> link time?

Short answer: Yes because you are using an "implicit" linking mechanism

Longer answer: Yes, but you can do better if necessary.

The issue is that your code makes an explicit reference to a function
external to the compilation unit. The compiler marks it as such. In the
world before DLLs, it was the job of the linker to "resolve" external
references and "bind" them to addresses by adding object code from external
sources (libraries and other compiled objects) to the executable image.

This behavior of the compiler doesn't change when DLLs are present. Adding
the the DLL's import library resolves all the references to each imported
function to a single address which contains a jump instruction whose target
is left blank. This unresolved reference is called an "import". At load
time, Windows maps the DLLs that you reference into your process, notes the
addresses of all of the (possibly relocated) imported functions contained in
the DLLs and then patches the import table so those jump instructions are
not jumps to nowhere.

With that simplified explanation, you can see if you don't supply an import
library for the DLL that you will have unresolved references. That's a
no-no.

There are at least two ways to defer the resolution of imports until
runtime. One is to call the DLL functions via pointers. You can get the
pointer to a function by calling LoadLibrary() followed by GetProcAddress().
The other way is to let the compiler and linker do this for you, it is
called delay loading.

Both techniques, have their place. But for now, I think you should go with t
he simple answer. :-)

Regards,
Will



Re: DLL and external references by alias

alias
Thu Jul 15 15:08:36 CDT 2004


Thank you, I was trying mimic the shared library behavior from Unix, but
since DLL are essentially EXE's and not just shared objects since it won't
work for my purpose.

A little more description of what I was trying to do:

I was trying to convert a static library into a DLL. The static library is
used to build an application. The "static library" uses functions from some
other static libraries. So to convert just that static library to a DLL I
would essentially have to resolve all external calls, which gets quite
involved and intricate and creates a huge DLL (the original EXE, almost).

Is my understanding correct?

Victor Bazarov <v.Abazarov@comAcast.net> wrote in
news:eWauhnpaEHA.3892@TK2MSFTNGP10.phx.gbl:

>
> Not sure I understand this question. An EXE is essentially a DLL.
> So, when a DLL is built, all external references need to be resolved.
> If the function uses static binding (comes from a static library),
> the library has to be supplied at the time of linking. If the symbol
> (function) uses dynamic binding (comes from a DLL), the _import_
> library needs to be supplied at the time of linking.
>
> Basically, there is no difference in linking a DLL or an EXE. The
> latter doesn't produce the import lib (usually), and has a different
> file extension. The inner format and ways to resolve symbols are
> essentially the same.
>
> Victor


Re: DLL and external references by alias

alias
Thu Jul 15 15:17:09 CDT 2004


Thank you for the explanation, I was trying to use a DLL like a shared
library on UNIX.



"William DePalo [MVP VC++]" <willd.no.spam@mvps.org> wrote in
news:#7AiVwpaEHA.3692@TK2MSFTNGP09.phx.gbl:
>
> Short answer: Yes because you are using an "implicit" linking mechanism
>
> Longer answer: Yes, but you can do better if necessary.
>
> The issue is that your code makes an explicit reference to a function
> external to the compilation unit. The compiler marks it as such. In the
> world before DLLs, it was the job of the linker to "resolve" external
> references and "bind" them to addresses by adding object code from
> external sources (libraries and other compiled objects) to the
> executable image.
>
> This behavior of the compiler doesn't change when DLLs are present.
> Adding the the DLL's import library resolves all the references to each
> imported function to a single address which contains a jump instruction
> whose target is left blank. This unresolved reference is called an
> "import". At load time, Windows maps the DLLs that you reference into
> your process, notes the addresses of all of the (possibly relocated)
> imported functions contained in the DLLs and then patches the import
> table so those jump instructions are not jumps to nowhere.
>


Re: DLL and external references by Victor

Victor
Thu Jul 15 16:16:19 CDT 2004

alias.name wrote:
> Thank you, I was trying mimic the shared library behavior from Unix, but
> since DLL are essentially EXE's and not just shared objects since it won't
> work for my purpose.

I am not sure I understand that statement about shared objects. In order
to use shared objects on Unix, you still need to link them in. Each .so
object serves as its own import library. On Windows a DLL is not its own
.LIB, that information is pulled into a different file, that's all.

So, mimicking Unix behaviour is what Windows does with DLLs.

>
> A little more description of what I was trying to do:
>
> I was trying to convert a static library into a DLL. The static library is
> used to build an application. The "static library" uses functions from some
> other static libraries. So to convert just that static library to a DLL I
> would essentially have to resolve all external calls, which gets quite
> involved and intricate and creates a huge DLL (the original EXE, almost).
>
> Is my understanding correct?

Yes. In order to prevent that, you need to create all those libraries
into DLLs.

The negative thing about static libraries mixed with DLLs is that if
your EXE uses a bunch of static library functions and your DLL uses the
same (or almost the same) set of library functions, those function will
be linked in twice, once into the DLL and the other time into the EXE,
after which the EXE will link to the DLL's import library and resolve
the few links DLLs provides.

Think of plain inheritance versus virtual inheritance in C++. In case
with static library used by both the DLL and the EXE, a copy of those
static library routines is placed into both EXE and DLL during linking.
That's why it's commonly recommended that if you have a project that
creates some DLLs and an EXE, you'd be much better off if the run-time
library is used as another DLL because in that case the code for all
the functions in the run-time library is not duplicated in those EXE/DLL
modules but pulled in during run-time.

Oh, if you happen to care, perhaps you will find it possible not to
top-post next time... Thanks.

>
> Victor Bazarov <v.Abazarov@comAcast.net> wrote in
> news:eWauhnpaEHA.3892@TK2MSFTNGP10.phx.gbl:
>
>
>>Not sure I understand this question. An EXE is essentially a DLL.
>>So, when a DLL is built, all external references need to be resolved.
>>If the function uses static binding (comes from a static library),
>>the library has to be supplied at the time of linking. If the symbol
>>(function) uses dynamic binding (comes from a DLL), the _import_
>>library needs to be supplied at the time of linking.
>>
>>Basically, there is no difference in linking a DLL or an EXE. The
>>latter doesn't produce the import lib (usually), and has a different
>>file extension. The inner format and ways to resolve symbols are
>>essentially the same.
>>
>>Victor
>
>


--
Please remove capital As from my address when replying by mail

Re: DLL and external references by Carl

Carl
Thu Jul 15 16:27:31 CDT 2004

Victor Bazarov wrote:
> alias.name wrote:
>> Thank you, I was trying mimic the shared library behavior from Unix,
>> but since DLL are essentially EXE's and not just shared objects
>> since it won't work for my purpose.
>
> I am not sure I understand that statement about shared objects. In
> order to use shared objects on Unix, you still need to link them in.
> Each .so object serves as its own import library. On Windows a DLL
> is not its own .LIB, that information is pulled into a different
> file, that's all.
>
> So, mimicking Unix behaviour is what Windows does with DLLs.

Not quite. An .so can have unsatisfied externals while a DLL cannot. The
dynamic linker will attempt to resolve those externals when the .so is
loaded using symbols available in all the other modules loaded into the
image.

The key difference is that windows doesn't have a dynamic linker - only a
dynamic loader that does little more than update a fixed table of
entry-point addresses when a module (DLL) is loaded.

-cd



Re: DLL and external references by alias

alias
Thu Jul 15 16:28:40 CDT 2004

Victor Bazarov <v.Abazarov@comAcast.net> wrote in
news:e4JN6DraEHA.2944@TK2MSFTNGP11.phx.gbl:

> alias.name wrote:
>> Thank you, I was trying mimic the shared library behavior from Unix,
>> but since DLL are essentially EXE's and not just shared objects since
>> it won't work for my purpose.
>
> I am not sure I understand that statement about shared objects. In
> order to use shared objects on Unix, you still need to link them in.
> Each .so object serves as its own import library. On Windows a DLL is
> not its own .LIB, that information is pulled into a different file,
> that's all.
>
>

Sorry about top posting and thank you for your help.

On Unix a shared library can have "unresolved external function calls" that
need to be resolved when the ".so" is linked into an application. But it
looks like a "DLL" on windows must be completely self containing.



Re: DLL and external references by Victor

Victor
Thu Jul 15 17:12:43 CDT 2004

Carl Daniel [VC++ MVP] wrote:
> Victor Bazarov wrote:
>
>>alias.name wrote:
>>
>>>Thank you, I was trying mimic the shared library behavior from Unix,
>>>but since DLL are essentially EXE's and not just shared objects
>>>since it won't work for my purpose.
>>
>>I am not sure I understand that statement about shared objects. In
>>order to use shared objects on Unix, you still need to link them in.
>>Each .so object serves as its own import library. On Windows a DLL
>>is not its own .LIB, that information is pulled into a different
>>file, that's all.
>>
>>So, mimicking Unix behaviour is what Windows does with DLLs.
>
>
> Not quite. An .so can have unsatisfied externals while a DLL cannot. The
> dynamic linker will attempt to resolve those externals when the .so is
> loaded using symbols available in all the other modules loaded into the
> image.
>
> The key difference is that windows doesn't have a dynamic linker - only a
> dynamic loader that does little more than update a fixed table of
> entry-point addresses when a module (DLL) is loaded.

OK, let me understand something... If I remove a .so file from my
disk and try to run an application that needs it, the dynamic linker
won't be able to resolve some references, right? If I remove a DLL
from my disk and try to run the EXE that needs it, the dynamic loader
won't be able to locate the DLL, right? So, that's one difference.
Or is it?

If I replace a .so file with a different one that has a symbol with
the same name, but different content, I can be screwed because it
will attempt to use that symbol in the way the old symbol was supposed
to be used. If I replace a DLL with another one that has an exported
symbol with the same name, the dynamic loader will resolve the address
but I can be screwed basically for the same reason as in Unix. No
difference here. Or is there?

If on Unix I have

link -o executable executable.o object1.so object2.so
./executable

, and when 'executable' needs 'symbol1', and it's not found in
'object1.so', it _might_ be found in 'object2.so' during _run-time_,
while on Windows if I have

link executable.obj object1.lib object2.lib -o exe.exe
exe.exe

finding the symbol has to happen during link-time, right? I am baffled
a bit. So, where's the real difference? If after linking I suddenly
replace 'object1.so' and 'object2.so' with new versions, such that
'Symbol1' _migrated_ from 'object1.so' to the other SO, then I don't have
to re-link, while on Windows I will have to relink, right? Is that the
real difference?

Thanks.

V

Re: DLL and external references by Carl

Carl
Thu Jul 15 18:24:04 CDT 2004

Victor Bazarov wrote:
> If after linking I
> suddenly replace 'object1.so' and 'object2.so' with new versions,
> such that 'Symbol1' _migrated_ from 'object1.so' to the other SO,
> then I don't have to re-link, while on Windows I will have to relink,
> right? Is that the real difference?

That's one scenario that illustrates the difference. In a DLL, all
externals are bound at link time - extern void foo() will be bound either to
something linked in the DLL explicitly, or to a matching import record from
an import library. Matching an import library record binds foo to a
particular DLL. Contrast that to the .so case where the unsatisfied foo()
is simply unsatisfied when the .so is built. The .so neither knows nor
cares what satisfies foo(), it just needs something to supply it. The *nix
model is more flexible, in some ways easier, and in some ways more fragile.

-cd