public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* mingw32: .exe -> .a import libs for DLLs?
@ 1998-01-17 11:14 Peter Dalgaard BSA
  1998-01-19 15:26 ` Fergus Henderson
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Dalgaard BSA @ 1998-01-17 11:14 UTC (permalink / raw)
  To: gnu-win32

Arrrgh. I've been messing around with dlltool and friends all day,
trying to get a DLL to modify a global variable with mingw32, or
rather Werner Koch's cross-development version of it. Basically, I
want to (various bits removed for brevity, so this won't actually run;
dl-routines lifted from Luke Tierney's web page at 
http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html ):

-----------
dltest.c:

int zip = 0;
void baz(void);

main(int argc, char *argv[])
{
  void  *libb;
  void (*foo)(void), (*bar)(void);

  libb = dlopen("b.dll", RTLD_NOW);
  bar = dlsym(libb, barsym);
  printf("zip is @%x\n",&zip);
  printf("baz is @%x\n",&baz);

  bar();
  dlclose(libb);
}

void baz()
{
  printf("baz called; zip = %d\n", zip);
}
---------
b.c:

void bar()
{
  printf("incrementing zip @%x\n", &zip);
  zip++;
  printf("calling baz @%x\n", &baz);
  baz();
  printf("done with bar\n");
}
------------

OK, so I follow the instruction to make b.dll (relocatable, a.m. John
Cerney) and dltest.exe. To access baz and zip, I tried to use the
usual procedure for creating export and import libs for dltest and
linking them into dltest.exe and b.dll, respectively. This works, as
far as loading b.dll and invoking it, but the addresses of zip and baz
are not the same in the two modules, so the zip++ naturally generates
a GPF. Obviously, they aren't getting properly relocated. I think what
I need is a dltest.a with the load addresses hardcoded, but how do I
do that?

Apparently, the commercial compilers know how to do this (nudge,
nudge, know what I mean?) in each their different way.

There are some notes on Fergus's page on building DLL's with gnuwin32,
but quite honestly, I cannot make heads or tails of them...

-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk)             FAX: (+45) 35327907

-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mingw32: .exe -> .a import libs for DLLs?
  1998-01-17 11:14 mingw32: .exe -> .a import libs for DLLs? Peter Dalgaard BSA
@ 1998-01-19 15:26 ` Fergus Henderson
  1998-01-19 17:06   ` Peter Dalgaard BSA
  0 siblings, 1 reply; 4+ messages in thread
From: Fergus Henderson @ 1998-01-19 15:26 UTC (permalink / raw)
  To: Peter Dalgaard BSA; +Cc: gnu-win32

On 17-Jan-1998, Peter Dalgaard BSA <p.dalgaard@biostat.ku.dk> wrote:
> Arrrgh. I've been messing around with dlltool and friends all day,
> trying to get a DLL to modify a global variable with mingw32, or
> rather Werner Koch's cross-development version of it. Basically, I
> want to (various bits removed for brevity, so this won't actually run;
> dl-routines lifted from Luke Tierney's web page at 
> http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html ):
> 
> -----------
> dltest.c:
> 
> int zip = 0;
> void baz(void);
> 
> main(int argc, char *argv[])
> {
>   void  *libb;
>   void (*foo)(void), (*bar)(void);
> 
>   libb = dlopen("b.dll", RTLD_NOW);
>   bar = dlsym(libb, barsym);
>   printf("zip is @%x\n",&zip);
>   printf("baz is @%x\n",&baz);
> 
>   bar();
>   dlclose(libb);
> }
> 
> void baz()
> {
>   printf("baz called; zip = %d\n", zip);
> }
> ---------
> b.c:
> 
> void bar()
> {
>   printf("incrementing zip @%x\n", &zip);
>   zip++;
>   printf("calling baz @%x\n", &baz);
>   baz();
>   printf("done with bar\n");
> }
> ------------
> 
> OK, so I follow the instruction to make b.dll (relocatable, a.m. John
> Cerney) and dltest.exe. To access baz and zip, I tried to use the
> usual procedure for creating export and import libs for dltest and
> linking them into dltest.exe and b.dll, respectively. This works, as
> far as loading b.dll and invoking it, but the addresses of zip and baz
> are not the same in the two modules, so the zip++ naturally generates
> a GPF. Obviously, they aren't getting properly relocated.

Does it work if you comment out the `zip++'?
I think the procedure that you have described should in theory
work for functions.  That is, in theory functions (but not global
variables) should get properly relocated.

For global variables, the import library will contain a
*pointer* to the global variable, i.e. for `zip', the
import library will contain a pointer `__imp_zip', and
in the module that uses it (b.c), you need to have

	#define zip (*__imp_zip)

The import library will also contain a definition of `zip',
but this will be entirely bogus -- it is a *function*.
(dlltool creates forwarding functions for every exported symbol,
without regard to whether the symbol is a function or not.)
That's why you were able to link "successfully", but zip++
gave a GPF.

> There are some notes on Fergus's page on building DLL's with gnuwin32,
> but quite honestly, I cannot make heads or tails of them...

The notes on my page don't cover the case of linking a DLL in dynamically
using dlopen() or its Win32 equivalent.  But if you have any specific
questions about them, I'd be happy to explain things.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: < http://www.cs.mu.oz.au/~fjh >   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mingw32: .exe -> .a import libs for DLLs?
  1998-01-19 15:26 ` Fergus Henderson
@ 1998-01-19 17:06   ` Peter Dalgaard BSA
  0 siblings, 0 replies; 4+ messages in thread
From: Peter Dalgaard BSA @ 1998-01-19 17:06 UTC (permalink / raw)
  To: Fergus Henderson; +Cc: Peter Dalgaard BSA, gnu-win32

Fergus Henderson <fjh@cs.mu.OZ.AU> writes:

> For global variables, the import library will contain a
> *pointer* to the global variable, i.e. for `zip', the
> import library will contain a pointer `__imp_zip', and
> in the module that uses it (b.c), you need to have
> 
> 	#define zip (*__imp_zip)

Thanx. I got a note from Colin Peters to the same effect, and by
Golly, it works...

> > There are some notes on Fergus's page on building DLL's with gnuwin32,
> > but quite honestly, I cannot make heads or tails of them...
> 
> The notes on my page don't cover the case of linking a DLL in dynamically
> using dlopen() or its Win32 equivalent.  But if you have any specific
> questions about them, I'd be happy to explain things.

Actually, dlopen seems to make things simpler since you don't need to
make import libs for the DLLs.  Luke Tierney's dl-stuff was never a
problem, those routines simply just worked.  

I've got a sketch of a fairly general Makefile set up. It follows
below if you're interested (otherwise just send it to the bit
bucket!). You don't need to tell me that it's a bit of a mess - I'm
getting a bit rusty on the Makefile business...

IMPLIBS=dltest.imp
all: dltest.exe a.dll b.dll
dltest.exe: dltest.o dlfcn.o dltest.exp
        gcc -o $@ $^ -lcrtdll
dltest.o: ../dltest.c
        gcc -I../../Win -c ../dltest.c
dlfcn.o:        ../../Win/dlfcn.c
        gcc -I../../Win -c ../../Win/dlfcn.c
dltest.ex1: dltest.o dlfcn.o
        gcc  -o dltest.ex1 dltest.o dlfcn.o -lcrtdll
dltest.def: dltest.ex1
        echo EXPORTS > dltest.def
        nm dltest.ex1 | grep '^........ [TD] _' | sed 's/[^_]*_//' >> dltest.def
%.imp: %.def %.ex1
        dlltool --dllname $*.exe --def $< --output-lib $@
%.exp: %.def %.ex1
        dlltool --dllname $*.exe --def $< --output-exp $@
%.imp: %.def %.dll
        dlltool --dllname $*.dll --def $< --output-lib $@
%.exp: %.def %.dll
        dlltool --dllname $*.dll --def $< --output-exp $@
a.o: ../a.c
        gcc -c $<
b.o: ../b.c
        gcc -c $<
dllstub.o: ../dllstub.c
        gcc -c $<
fixup.o: fixup.c
        gcc -c $<
%.def: %.o dllstub.o fixup.o
        echo EXPORTS > $@
        nm $< dllstub.o fixup.o | grep '^........ [T] _' | sed 's/[^_]*_//' >> $@
%.dll %.base %.exp: %.o %.def dllstub.o fixup.o $(IMPLIBS)
        ld --base-file $*.base --dll -o $@ $< dllstub.o fixup.o $(IMPLIBS) -lcrtdll -e _DllMain@12
        dlltool --dllname $*.dll --def $*.def --base-file $*.base --output-exp $*.exp
        ld --base-file $*.base  $*.exp --dll -o $*.dll $*.o dllstub.o fixup.o $(IMPLIBS) -lcrtdll -e _DllMain@12
        dlltool --dllname $*.dll --def $*.def --base-file $*.base --output-exp $*.exp
        ld --base-file $*.base  $*.exp --dll -o $*.dll $*.o dllstub.o fixup.o $(IMPLIBS) -lcrtdll -e _DllMain@12
-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk)             FAX: (+45) 35327907

-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mingw32: .exe -> .a import libs for DLLs?
@ 1998-01-19 10:32 Colin Peters
  0 siblings, 0 replies; 4+ messages in thread
From: Colin Peters @ 1998-01-19 10:32 UTC (permalink / raw)
  To: Peter Dalgaard BSA; +Cc: GNU-Win32

You almost have it. The problem is that the symbols baz and zip are
actually pointers to thunk functions in the DLL (and similarly the symbol
bar is a pointer to a thunk in the executable). The thunk functions simply
look up the appropriate pointer in the jump table for the DLL and call
that function. Obviously this won't work for variables. What you have to
do in that case is something like

extern int* __imp__zip;
#define zip    (*__imp__zip)

in your DLL code (but not in the executable). This only works because we
know that dlltool names each of the entries in the jump table
__imp_<symbol> (and the actual symbol for zip is _zip, but anyway). This
may change in the future (especially since MS's standard is something like
_imp___zip IIRC), but for now it will work.

On the other hand I'm sure you know that global variables are evil. :)

Good luck,
Colin.

PS. I think MS does this basically the same way, except the compiler knows
how to handle it all internally based on the __dllexport (or some such)
keyword.

-- Colin Peters -- colin at fu.is.saga-u.ac.jp
-- Saga University Dept. of Information Science
-- http://www.fu.is.saga-u.ac.jp/~colin
-- http://www.geocities.com/Tokyo/Towers/6162


-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1998-01-19 17:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-01-17 11:14 mingw32: .exe -> .a import libs for DLLs? Peter Dalgaard BSA
1998-01-19 15:26 ` Fergus Henderson
1998-01-19 17:06   ` Peter Dalgaard BSA
1998-01-19 10:32 Colin Peters

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).