From: gunther DOT ebert AT ixos-leipzig DOT de (Gunther Ebert) Subject: Re: export data from a b18 DLL? (stdout bug?) 30 Jul 1997 08:30:56 -0700 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: <33DF0FF4.D9.cygnus.gnu-win32@ixos-leipzig.de> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 2.01Gold (WinNT; I) Original-To: Ron Kulper Original-Cc: gnu-win32 AT cygnus DOT com Original-Sender: owner-gnu-win32 AT cygnus DOT com Ron Kulper wrote: > > Is it possible to export data (as opposed to a function) from a dll? Yes, in general it is but it is somewhat difficult. If you link a dll with exported data to a program you will not get a pointer to the actual data but to a jump instruction (the linker assumes that the pointer is to a function). An example: /* dll code fragment */ char *some_data = "string from dll"; /* exe code fragment */ extern char *some_data; void foo() { printf(some_data); } /* fails because some_data isn't valid */ This will run into a SIGSEGV because the some_data pointer is not valid, meaning it doesn't point to the "string from dll" data but to some jump instructions. However, ld generates another symbol for every item which is exported by a dll. The name of the new symbol is the name itself with a preceding "__imp__". This symbol contains the address of the actual data, use this instead. The code fragments will change to /* dll code fragment */ char *some_data = "string from a dll"; /* exe code fragment */ extern char *__imp__some_data; void foo() { printf(__imp__some_data); } /* Ok */ This works for gcc, but this isn't portable at all because it depends on the naming conventions which are used by the linker to generate the extra symbol. I know for sure that this doesn't work with MSVC. Anyway, I would suggest not exporting data directly. Write data access functions and export them instead of the actual data. > For instance, can I access a malloc'ed structure located in one dll > from a different dll by exporting a structure pointer to the allocated > space? I know this can be done in MSVC++, but when I try it using > cygwin32, I receive a SIGSEGV when attempting to reference the pointer. > Does this issue have anything to do with the bug described below? > > I recieve a SIGSEGV when attempting to set a FILE * = stdout within a dll. > Platform is NT4.0SP3 on a pentium with cygwin32 beta 18. No, this is a completely different problem. The stdout pointer isn't valid because it isn't initialized when your dll has been loaded. You cannot build a dll which uses cygwin functions which need initializing. This is because there isn't any dllcrt0.o module which contains the correct startup code for a dll (i.e. the appropriate dll_entry function) which uses cygwin.dll. > > The problem can be recreated with the 5 small files below. > "dbpcc8.sh stdout" will create stdout.dll > gcc -g main2.c creates a.exe which tries to load C:\tmp\stdout.dll and > call stdout_dll(). > init.cc and fixup.c are the standard files included for completeness. > The SIGSEGV occurs at line 7 of stdout.c "fp=stdout". > > Any help resolving this problem is appreciated. > > Thanks, > Ron Kulper > ron AT dbpower DOT com > > stdout.c > -------------------------------------------------------------------------------- > #include > > void > stdout_dll() > { > FILE *fp; > fp=stdout; > fprintf(fp,"hello\n"); > } > main() > { > stdout_dll(); > } > -------------------------------------------------------------------------------- > > main2.c > -------------------------------------------------------------------------------- > #include > #include "windows.h" > > typedef void (*vfp)(); > > main() > { > vfp dbp_init_func; > HINSTANCE lib_handle = LoadLibrary("c:\\tmp\\stdout.dll"); > if(lib_handle == NULL) > { > perror("Error loading DLL"); > exit(0); > } > > dbp_init_func = (vfp) GetProcAddress(lib_handle, "stdout_dll"); > if(dbp_init_func == NULL) > { > perror("Error loading func dbp_init_report"); > exit(0); > } > > dbp_init_func(); > > FreeLibrary(lib_handle); > } > -------------------------------------------------------------------------------- > > dbpcc8.sh > -------------------------------------------------------------------------------- > export LIBPATH="C:/gnuwin32/b18/H-i386-cygwin32/i386-cygwin32/lib" > echo EXPORTS > $1.def > gcc -DCYGWIN32 -g -c $1.c > nm $1.o | grep '^........ [T] _'|sed 's/[^_]*_//' >> $1.def > ld --base-file $1.base --dll -o $1.dll $1.o init.o fixup.o $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry AT 12 > dlltool --as=as --dllname $1.dll --def $1.def --base-file $1.base --output-exp $1.exp > ld --base-file $1.base $1.exp --dll -o $1.dll $1.o init.o fixup.o $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry AT 12 > dlltool --as=as --dllname $1.dll --def $1.def --base-file $1.base --output-exp $1.exp > ld $1.exp --dll -o $1.dll $1.o init.o fixup.o $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry AT 12 > dlltool --as=as --dllname $1.dll --def $1.def --output-lib $1.a > -------------------------------------------------------------------------------- > > init.cc > -------------------------------------------------------------------------------- > /* #include GNU version 2 copyright */ > #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; > } > -------------------------------------------------------------------------------- > > fixup.c > -------------------------------------------------------------------------------- > asm(".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0"); > -------------------------------------------------------------------------------- > > - > For help on using this list (especially unsubscribing), send a message to > "gnu-win32-request AT cygnus DOT com" with one line of text: "help". -- Gunther Ebert iXOS Anwendungs-Software GmbH Angerstrasse 40-42 D-04177 Leipzig Phone : +49 341 48503-0 Fax : +49 341 48503-99 E-mail: mailto:gunther DOT ebert AT ixos-leipzig DOT de www : http://www.ixos-leipzig.de - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".