public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* RE: Can't Reference Stderr from a DLL
@ 1997-03-18  9:38 Sergey Okhapkin
  1997-03-18  9:38 ` John Cerney
  0 siblings, 1 reply; 8+ messages in thread
From: Sergey Okhapkin @ 1997-03-18  9:38 UTC (permalink / raw)
  To: gnu-win32, 'John Cerney'

John Cerney wrote:
> >  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...
>
> 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.

It's not a suitable way for me :-( It requires explicit call to 
impure_setup() for _each_ project's dll! This will prevent easy porting (X 
stuff for example). If reent_data will be exported from within cygwin.dll, 
then it will be possible to write

#include <windows.h>
extern struct reent *_impure_ptr, *__imp_reent_data;
int WINAPI dll_main(HANDLE a, DWORD reason, void *q)
{ switch (reason){
   case DLL_PROCESS_ATTACH: break;
   case DLL_PROCESS_DETACH: break;
   case DLL_THREAD_ATTACH:  break;
   case DLL_THREAD_DETACH:  break;
  }
  _impure_ptr = __imp_reent_data;
  return 1;
}

and link this file to every DLL. Function dll_main (declared as entry point 
on ld's command line) will be called automatically after loading dll, and 
will set up dll's _impure_ptr right without explicit call to it! Number of 
dll's may vary - initialisation for each dll will be done automatically.

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

This technique is used in a port of X libraries with MSVC :-)

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

VC++ requires explicit dllimport/dllexport declarations. Almost the same 
way...

--
Sergey Okhapkin
Moscow, Russia
Looking for a job.


-
For help on using this list, send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 8+ messages in thread
* RE: Can't Reference Stderr from a DLL
@ 1997-03-17 14:51 Sergey Okhapkin
  1997-03-17 14:51 ` John Cerney
  0 siblings, 1 reply; 8+ messages in thread
From: Sergey Okhapkin @ 1997-03-17 14:51 UTC (permalink / raw)
  To: gnu-win32, 'John Cerney'

John Cerney wrote:
> Thanks for the input on the problem. I ended up puting in a impure_ptr
> initialization
> routine that is called by my main program before it uses any functions in 
a
> DLL.

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

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

--
Sergey Okhapkin
Moscow, Russia
Looking for a job

-
For help on using this list, send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 8+ messages in thread
* RE: Can't Reference Stderr from a DLL
@ 1997-03-13  6:25 Sergey Okhapkin
  1997-03-17  9:29 ` John Cerney
  0 siblings, 1 reply; 8+ messages in thread
From: Sergey Okhapkin @ 1997-03-13  6:25 UTC (permalink / raw)
  To: gnu-win32, 'John Cerney'

John Cerney wrote:
> I've run into problem trying to build a dynamic lib version of 
perl5.003_25.
>
> Looking at the cygwin.dll source code, it appears that stderr is 
translated to
> _impure_ptr->stderr by the defines inside of the <stdio.h> 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.
>

This is due to _impure_ptr in a main program and in DLL are _different_ 
variables! And _impure_ptr in a DLL is not initialised to point to 
reent_data structure in a main program. I have the same troubles with X 
libraries builded as DLL. I already wrote mr. Noer about this bug, no 
answer for a now...

--
Sergey Okhapkin
Moscow, Russia
Looking for a job.


-
For help on using this list, send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 8+ messages in thread
* Can't Reference Stderr from a DLL
@ 1997-03-12  6:22 John Cerney
  1997-03-12 13:11 ` Fergus Henderson
  0 siblings, 1 reply; 8+ messages in thread
From: John Cerney @ 1997-03-12  6:22 UTC (permalink / raw)
  To: gnu-win32

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@4'
libcmain.cc:30: undefined reference to `GetCommandLineA@0'
libcmain.cc:30: undefined reference to `WinMain@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 <stdio.h> 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 <stdio.h>


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 <windows.h> 

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@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@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@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@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1997-03-18  9:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-03-18  9:38 Can't Reference Stderr from a DLL Sergey Okhapkin
1997-03-18  9:38 ` John Cerney
  -- strict thread matches above, loose matches on Subject: below --
1997-03-17 14:51 Sergey Okhapkin
1997-03-17 14:51 ` John Cerney
1997-03-13  6:25 Sergey Okhapkin
1997-03-17  9:29 ` John Cerney
1997-03-12  6:22 John Cerney
1997-03-12 13:11 ` Fergus Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).