From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Cerney To: "gnu-win32@cygnus.com" , Sergey Okhapkin Subject: RE: Can't Reference Stderr from a DLL Date: Mon, 17 Mar 1997 14:51:00 -0000 Message-id: References: <01BC332D.57BADC20@sos> X-SW-Source: 1997-03/msg00258.html > How did you initialize _local_ for a DLL _impure_ptr? Main program knows > nothing about it! The only way I see is to place reent_data structure to > cygwin.dll and modify fork() code to create a copy of it in a child > process... > I included 3 files at the end of this message that are a simple example of the technique I used. main.c : main executable; calls impure_setup with its impure_ptr as an arg foo.c : dll file init.cc: dll file, contains the dll initialization functions. main.c calls impure_setup() in the dll with main's impure_ptr as its argument impure_setup() in init.cc takes the impure_ptr from main and copies the value to its (the dll's) local copy of impure_ptr. The Actual application I am trying to port (perl5.003_25) has one function that loads DLLs at runtime. It was fairly simple to modify this function so that is calls the impure_setup function just after it loads the DLLs. This solved my problem with impure_ptr in DLLs. Now my problem is the DLLs need to access some global variables in the perl executable. > > Have you had any luck exporting global data variables from/to a DLL? > > Place var_name to a .def file, build a dll and import library. Now You can > access this global data - variable __imp_var_name contains the pointer to > var_name. > I was afraid you were going to say that :) I guess this means that I will have to create a include file that does something like this for every global variable I want to access: #define variableName (*_imp_variableName) I wish there was a more transparent way of doing this. I believe VC++ allows you to access global variables to/from DLLs without going to this trouble. I am trying to build the VC++ win32 port of perl 5.003 now to verify if this is true. Thanks, John ******************* Example Files********************************* ***** File main.c ***** // Main file to try linking with a DLL under gnuwin32 // Includes call a dll function to initialize it's impure_ptr #include extern int doit(int, FILE *); extern void impure_setup(struct _reent *); int main() { // setup the DLLs impure_ptr: impure_setup(_impure_ptr); printf("doit(5) returns %d\n", doit(5,stderr)); } ****** File foo.c ***** // This file is one of the files that makes up foo.dll // Test file to check out building DLLs with gnuwin32 // This uses printf from the std lib #include //* function declarations: *** int doit (int i, FILE *a); int doit (int i, FILE *a) { printf("In foo.c inside of doit with printf\n"); fputs("In foo.c inside of doit, with fputs main stderr\n",a); fputs("In foo.c inside of doit, with fputs stderr\n",stderr); return( 4 ); } ******* File init.cc ************ // This file is one of the one that makes up the foo.dll library // DLL entry point module // Added impure_ptr initialization routine. This is needed for any DLL that needs // to output to the main (calling) executable's stdout, stderr, etc. This routine // needs to be called from the executable using the DLL before any other DLL // routines are called #include extern "C" { int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr); void impure_setup(struct _reent *_impure_ptrMain); }; struct _reent *_impure_ptr; // this will be the Dlls local copy of impure 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; } // // Function to set our local (in this dll) copy of impure_ptr to the // main's (calling executable's) impure_ptr void impure_setup(struct _reent *_impure_ptrMain){ _impure_ptr = _impure_ptrMain; } - For help on using this list, send a message to "gnu-win32-request@cygnus.com" with one line of text: "help".