This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Importing a variable from a DLL


 
--

On Thu, 26 Aug 1999 01:29:22   Mumit Khan wrote:
>James Stern <jsternitg@yahoo.com> writes:
>> 
>> As I understand it, the situtation is this:  Suppose
>> that source file s1.cc used in main.exe references
>> extern variable v1 from the DLL.  Then s1.cc has to
>> declare v1 as __declspec (dllimport).  If s2.cc
>> through s20.cc also use v1, they must do likewise.
>> 

This is a sticking point on a # of compilers. I have
used extern int * foo in place of 
__declspec(dllimort) int *foo, 
and it works. I have 
been told that extern int foo,
definately can't replace __declspec(dllimport) int foo,
but I havn't tried it.

The brutal truth is that there is very little
uniformity between compilers and binary code on this
point. I have seen dll libraries that worked fine
fall to work on a new version of the pentium chip.
I have seen dll libraries that worked fine with
one compiler, fail to export the pointer segment to
another compile.

The only way to know is trial and error. Even then
you will need good luck every time Intel or Microsoft
decide to change anything.

I have attached a detailed responce from Bernud in
the Powersoft C++ forum on a simular question:

Clark Sims wrote:
> 
> System: Windows 98/NT
> Compiler: Watcom C 11.0
> 
> I have several libraries where I am exporting both classes and
> functions. When is it necessary to declare a class or function as
> declspec dllimport?
> 
> Thanks in Advance,
> 
> Clark Sims

It's necessary to declare objects (C objects, that is data stuff as
opposed to functions) __declspec(dllimport). Imported functions will get
a slight performance boost from it, but variables without
__declspec(dllimport) will not work at all.

The reason is the import address table that is used for DLL imports. It
is a function stub consisting of a jump to the "real" address, the real
address will be fixed at runtime when loading the DLL.

If it's a function then the called address will, without
__declspec(dllimport), be the stub's address. This doesn't hurt very
much (you get an additional jmp when calling a DLL function), but with
__declspec(dllimport) the jump can be avoided; the compiler will call
the jmp target address indirectly, bypassing the jmp instruction.

Objects are treated just like functions, however, and you don't want
your imported variable to be treated as if located at a jump instruction
in the import address table. Therefore you may not import objects
without telling the compiler they are imported. Telling the compiler
it's in fact a DLL imported variable will allow it to use a pointer to
access the variable indirectly, and the pointer is considered to be
located where the jump target for functions is fetched from, in the
import address table; so a
  extern __declspec(dllimport) int foo;
is in fact treated like a
  extern int *foo;
by the compiler. This works nicely.

You can see the effect in the disassembler listing. Imports without
__declspec(dllimport) are decorated normally and treated according to
their declaration, and imports with __declspec(dllimport) get a
prepended "__imp_" to their name and have an additional indirection.





--== Sent via Deja.com http://www.deja.com/ ==--
Share what you know. Learn what you don't.

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]