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: Can't build a DLL using gcc


Carl Thompson wrote:
> 
> I wrote a message to the list the other day about a much easier way to
> create DLLs using Cygwin than using dlltool, dllhelpers and .def files.  You
> can see it at
> 
>    http://sourceware.cygnus.com/ml/cygwin/2000-06/msg00688.html
> 
> This method is not only easier, but also allows you to maintain your symbol
> information in one place-- the header files where they belong.  You don't
> have to try to keep separate .def files in sync.
> 
> Even if you choose to keep using .def files, I believe you can use the newer
> method to actually create the DLLs anyway.  This might cure your problem.  I
> highly recommend not using .def files and using the technique described in
> my message.  It guarantees that the symbols you want to export are exported
> correctly.
> 
> I know this method works because I use it for non trivial projects.  It's
> quite possible the documentation you looked at is outdated or inaccurate.
> 
> Hope this helps,
> Carl Thompson

You probably *should* use def files if (a) you're developing a library
that other folks might want to use, without recompiling their
application code, and (b) you want to support those apps that
'import-by-number' from the dll. With the no-def-file method, you're
never guaranteed that the name/numbers will be the same from build to
build. That is:

----sample def file 1-----
EXPORTS
   my_func1 @1
   my_func2 @2
------------------------

Suppose the first time you build your library dll using the no-def-file
method, it generates the dll as described by the sample def file #1
above (by luck or what have you).

Then, another developer ('John') uses your dll to write an application,
and links by number. So he accesses my_func1 via the dll-position number
'@1' and my_func2 via '@2'.

Later, you add a new function to your library, new_func. Then, you
rebuild the dll, and (by luck or what have you) the dll is built
according to the following def file:

----sample def file 2-----
EXPORTS
   new_func @1
   my_func1 @2
   my_func2 @3
--------------------------

John's app won't work with the new dll unless he recompiles, since '@1'
isn't my_func1 anymore.

I'm not sure what controls whether an app links by the export name or by
the position number, so I try to allow both to work from version to
version of a given dll, by using an explicit def file. Just add new
functions to the end.

--Chuck


> 
> kulack@us.ibm.com wrote:
> >
> > I'm pretty new at Win and gcc development. I've been searching the archives
> > for details about this, but have only found hints.
> > I've followed the instrutions at
> > http://sourceware.cygnus.com/cygwin/cygwin-ug-net/dll.html for building
> > DLLs using GCC, but get a STATUS_ACCESS_VIOLATION when I attempt to use it.
> >
> > About my only guess is that I'm doing something wrong with the .DEF file.
> > Can it get created automatically or should there be a 'SECTIONS' section in
> > the .DEF file indicating which type of access (EXECUTE, READ, WRITE) the
> > dll should have?
> > Not familiar with nm output, but it seems to look ok for the created dll...
> > Can anyone teach me to fish? 8-)
> >
> > Bash /db2src/test
> >  > make libhello.a
> > gcc  -g -c -I/sqllib/include libhello.c
> > gcc -s -Wl,--base-file,libhello.base -o libhello.dll libhello.o
> > -Wl,-e,_mydll_init@12
> > dlltool --base-file libhello.base --def libhello.def --output-exp
> > libhello.exp --dllname libhello.dll
> > gcc -s -Wl,--base-file,libhello.base,libhello.exp -o libhello.dll
> > libhello.o -Wl,-e,_mydll_init@12
> > dlltool --base-file libhello.base --def libhello.def --output-exp
> > libhello.exp --dllname libhello.dll
> > gcc -Wl,libhello.exp -o libhello.dll libhello.o -Wl,-e,_mydll_init@12
> > dlltool --def libhello.def --dllname libhello.dll --output-lib libhello.a
> > cp libhello.dll ..
> > rm libhello.o
> >
> > Bash /db2src/test
> >  > make hello.exe
> > gcc  -g -c -I/sqllib/include hello.c
> > gcc  -g hello.o -L/db2src/test -lhello
> > mv a.exe hello.exe
> >
> > Bash /db2src/test
> >  > hello
> > Hello World
> >       0 [main] hello 1127 handle_exceptions: Exception:
> > STATUS_ACCESS_VIOLATION
> >    9205 [main] hello 1127 stackdump: Dumping stack trace to
> > hello.exe.stackdump
> >
> > Bash /db2src/test
> >  > cat hello.exe.stackdump
> > Exception: STATUS_ACCESS_VIOLATION at eip=000055CC
> > eax=00000009 ebx=00000000 ecx=0000000C edx=0245FDF4 esi=00000000
> > edi=0A041448
> > ebp=0245FE74 esp=0245FE58 program=c:\db2src\test\hello.exe
> > cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
> > Stack trace:
> > Frame     Function  Args
> > 0245FE74  00401085  (00000009, 0245FEB0, 0245FEA4, 0040106B)
> > 0245FEA4  00401085  (00000001, 0A041448, 0A040008, 00000000)
> > 0245FF00  610022E5  (7FFDF000, 00000000, 00000018, 80452662)
> > 0245FF60  61002735  (00403010, 00000000, 0245FF90, 004011DA)
> > 0245FF90  004011E7  (00401060, FFFFFFFF, 80430B27, 00000000)
> > 0245FFC0  0040103B  (00000018, 00000000, 7FFDF000, 00000000)
> > 0245FFF0  77E87903  (00401000, 00000000, 000000C8, 00000100)
> > End of stack trace
> >
> > ======= libhello.c
> > #include <stdio.h>
> > #include <windows.h>
> > extern int helloFromDll(int parm);
> >
> > int WINAPI
> > mydll_init(HANDLE h, DWORD reason, void *foo)
> > {
> >    return 1;
> > }
> >
> > int helloFromDll(int parm) {
> >    printf("Hello from Dll, parm=%d\n", parm);
> >    return parm+1;
> > }
> >
> > int main(int argc, char **argv) {
> >    // This doesn't feel right...
> >    // Was forced to add main() in order to get the
> >    // instructions for building DLLs at
> >    //   http://sourceware.cygnus.com/cygwin/cygwin-ug-net/dll.html
> >    // to work correctly, otherwise, linker failed to
> >    // find WinMain@16 (which I wouldn't have believed it should
> >    // require).
> > }
> >
> > ======= libhello.def
> > LIBRARY LIBHELLO
> > DESCRIPTION 'LIBHELLO.DLL Testcase'
> > EXPORTS
> >    helloFromDll
> >
> > ======= hello.c
> > #include <stdio.h>
> > extern int helloFromDll(int parm);
> > int main(int argc, char **argv)
> > {
> >    int         rc;
> >    printf("Hello World\n");
> >    rc = helloFromDll(9);
> >    printf("DLL returned %d\n", rc);
> >    return 0;
> > }
> >
> > --
> > Want to unsubscribe from this list?
> > Send a message to cygwin-unsubscribe@sourceware.cygnus.com
> 
> --
> Want to unsubscribe from this list?
> Send a message to cygwin-unsubscribe@sourceware.cygnus.com

--
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]