From: Nick AT fys DOT ruu DOT nl (Nick van Eijndhoven) Subject: DLL problems understood, but not solved 19 Mar 1997 16:56:22 -0800 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: <199703191058.LAA18195.cygnus.gnu-win32@ruunat.fys.ruu.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Original-To: gnu-win32 AT cygnus DOT com Original-Cc: Nick AT fys DOT ruu DOT nl (Nick van Eijndhoven) X-Mailer: ELM [version 2.4 PL25] Original-Sender: owner-gnu-win32 AT cygnus DOT com Dear GNU developers, I think I have found the reason for my problems in creating a DLL from C++ source code using GCC version 2.7.2-961023 under windows95 To my opinion the problems are due to the fact that currently it is not (yet) possible to invoke a DLL from some other DLL. This occurred in my case, since I use 'cout' in the member functions of my class 'Funcs' from which I would like to make a DLL. Due to some obscure reason, some standard C++ stuff (like 'cout' etc...) has been put into the cygwin library with the consequence that my DLL invokes cygwin.dll and hence produces all sorts of cryptic errors. By changing the 'cout' into 'printf' in my member functions, all problems were solved and the test was successfully run (thanks to the nice examples concering relocatable DLL's from John Cerney and Gunther Ebert on the www). Note that I can use 'cout' in my test.cc main program (since this is not in a DLL) which confirms my diagnostics. So to my opinion what should be done to make the GNU product usable for DLL's is the following : 1) Move all standard C++ stuff out of cygwin and add it to libstdc++.a (where libstdc++.a is a normal static library). 2) Implement the possibility to invoke a DLL from another DLL. 3) Make sure that the GNU produced DLL's can be used together with the Microsoft visual C++ produced DLL's. This is vital in my case (being a member of a large high energy physics experiment where some packages use MS visual C++ stuff). Below I will provide all the files I used to perform my tests so that you can try things out for yourself. Note that I have used 'g++' instead of 'ld' in "dlltest.bat" which means that automatically I get all the needed standard libs linked in. It seems also that the extra 'ld' and 'dlltool' passes in John Cerney's example are not needed (at least in this test case). To see the errors appear, just change in (one of) the member functions the 'printf' into 'cout' and include the iostream.h. Cheers, Nick. *----------------------------------------------------------------------* Dr. Nick van Eijndhoven Department of Subatomic Physics email : nick AT fys DOT ruu DOT nl Utrecht University / NIKHEF tel. +31-30-2532331 (direct) P.O. Box 80.000 tel. +31-30-2531492 (secr.) NL-3508 TA Utrecht fax. +31-30-2518689 The Netherlands WWW : http://www.fys.ruu.nl/~nick Office : Ornstein lab. 172 ---------------------------------------------------------------------- tel. +41-22-7679751 (direct) CERN PPE Division / ALICE exp. tel. +41-22-7675857 (secr.) CH-1211 Geneva 23 fax. +41-22-7679480 Switzerland CERN beep : 13+7294 Office : B 160 1-012 *----------------------------------------------------------------------* ================== dlltest.bat @echo off rem *** Script to create and test a relocatable GNU-Win32 DLL from *.cc files *** rem --- The file init.cc provides the entry point for the DLL --- rem --- Create a special file fixup.cc needed for execution of the DLL --- echo asm (".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0"); >fixup.cc g++ -s -c Funcs.cc init.cc fixup.cc ar rs q.a *.o rem --- Create the .def file echo EXPORTS >q.def nm q.a | egrep " [CT] " | sed s/.........T._//g >q.scr sed s/.........C._//g q.scr >>q.def del q.scr rem --- Create the export file to build the DLL --- g++ -s -nostartfiles -Wl,--dll -e _dll_entry AT 12 -o q.dll -Wl,--base-file=q.base *.o dlltool --def=q.def --output-exp=q.exp --dllname=q.dll --output-lib=q.a --base-file=q.base rem --- Now actually create the DLL --- g++ -s -nostartfiles -Wl,--dll -e _dll_entry AT 12 -o q.dll *.o q.exp del fixup.cc del *.o del q.exp del q.def del q.base echo *** mkdll done, going for test ... g++ -s -o test.exe test.cc q.a test del test.exe del q.a del q.dll echo *** testing done. ============ init.cc // Facility to provide an entry point to a DLL #include extern "C" { int WINAPI dll_entry(HANDLE h, DWORD reason, void *ptr); }; int WINAPI dll_entry(HANDLE, DWORD reason, void *) { return 1; } ============== Funcs.h // Definitions of the functions for private test program class Funcs { public: Funcs(); void aap(); void noot(); void mies(); }; ================ Funcs.cc //#include #include #include "Funcs.h" Funcs::Funcs() { } void Funcs::aap() { // cout << "*** aap ***" << endl; printf("*** aap ***\n"); } void Funcs::noot() { // cout << "*** noot ***" << endl; printf("*** noot ***\n"); } void Funcs::mies() { // cout << "*** mies ***" << endl; printf("*** mies ***\n"); } ============== test.cc // Main program to test the class Funcs by using the DLL #include //#include #include "Funcs.h" void main() { Funcs q; cout << "q defined" << endl; // printf("q defined\n"); q.aap(); cout << "aap invoked" << endl; // printf("aap invoked\n"); q.noot(); cout << "noot invoked" << endl; // printf("noot invoked\n"); q.mies(); cout << "mies invoked" << endl; // printf("mies invoked\n"); } - For help on using this list, send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".