From: j-cerney1 AT ti DOT com (John Cerney) Subject: Can't Reference Stderr from a DLL 12 Mar 1997 09:06:02 -0800 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: Reply-To: John Cerney Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Mailer: BeyondMail for Windows/Professional 2.3 Original-To: gnu-win32 AT cygnus DOT com X-BeyondMail-Priority: 1 Conversation-ID: X-Receipt-From-Agent: true Original-Sender: owner-gnu-win32 AT cygnus DOT com I've run into problem trying to build a dynamic lib version of perl5.003_25. I believe I have narrowed it down to a referencing stderr or stdout in a dll. A simple test case which duplicates the problem is included at the end of this message. Specifically, if I build a dll that references stderr inside of it (like a fputs("test out",stderr) call inside the DLL) the linker complains about unresolved references: libcmain.cc:29: undefined reference to `GetModuleHandleA AT 4' libcmain.cc:30: undefined reference to `GetCommandLineA AT 0' libcmain.cc:30: undefined reference to `WinMain AT 16' When I remove the reference to stderr by replacing the fputs call with a simple printf, the dll builds and runs fine. Looking at the cygwin.dll source code, it appears that stderr is translated to _impure_ptr->stderr by the defines inside of the include. _impure_ptr is defined in libccrt0.cc inside of cygwin.dll, which also references main(). Does the linker try to resolve all references in an object file, even if you just refer to one variable that is defined in it? I have tried building the DLL using the --noinhibit-exec linker option. The dll is built in this case, but the main.exe executable crashes with a seg fault. Has anyone here seen this problem before? Does anyone know what is going on? -John *********** Simple Test Case ******* *** file foo.c *** // Test file to check out building DLLs with gnuwin32 // This uses printf from the std lib #include int doit (int i) { //printf("In foo.c inside of doit\n"); fputs("In foo.c inside of doit\n",stderr); return( 4 ); } *** File init.cc *** // DLL entry point module #include extern "C" { int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr); }; int WINAPI dll_entry (HANDLE , DWORD reason, void *) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return 1; } *** File fixup.c *** /* This is needed to terminate the list of import stuff */ /* Copied from winsup/dcrt0.cc in the cygwin32 source distribution. */ asm(".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0"); *** File Main.c *** // Main file to try linking with a DLL under gnuwin32 int main() { printf("doit(5) returns %d\n", doit(5)); } *** File buildLib **** #! /bin/sh # script to build the simple test case DLL and a the main executable that runs it # jc 3/12/97 LIBPATH=/gnuwin32/H-i386-cygwin32/i386-cygwin32/lib gcc -c foo.c gcc -c init.cc gcc -c fixup.c echo EXPORTS > foo.def nm foo.o init.o fixup.o | grep '^........ [T] _' | sed 's/[^_]*_//' >> foo.def # Link DLL. ld --base-file foo.base --dll -o foo.dll foo.o init.o fixup.o \ $LIBPATH/libcygwin.a -e _dll_entry AT 12 --noinhibit-exec dlltool --as=as --dllname foo.dll --def foo.def --base-file foo.base --output-exp foo.exp ld --base-file foo.base foo.exp --dll -o foo.dll foo.o init.o fixup.o \ $LIBPATH/libcygwin.a -e _dll_entry AT 12 --noinhibit-exec dlltool --as=as --dllname foo.dll --def foo.def --base-file foo.base --output-exp foo.exp ld foo.exp --dll -o foo.dll foo.o init.o fixup.o\ $LIBPATH/libcygwin.a -e _dll_entry AT 12 --noinhibit-exec # Build the foo.a lib to link to: dlltool --as=as --dllname foo.dll --def foo.def --output-lib foo.a # Linking with main gcc main.c foo.a -o main.exe - For help on using this list, send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".