Subject: Initialising DLLs, again
From: [email-masked] (Matthew Brett)

15 May 1998 20:28:54 -0700
Message-ID: <Pine.SUN.3.91.980515115613.15958A-100000.cygnus.gnu-win32@jaguar>
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
To: [email-masked]

Dear Friends,

I've been playing with b19 recently, and returning to a problem 
which started a certain amount of mail for b18; initialising
DLLs.  

My problem was that I wanted to use a Cygwin-generated DLL from
a non-Cygwin application, such as a MSVC program, matlab etc.
The difficulty was in initialising the C runtime in the 
cygwin19.dll, from my own DLL.  I had hoped this might be easier
in b19, from the comments in the FAQ - but so far, no dice.

I've followed various pointers in the FAQ and previous posts,
and can compile my relocatable DLL without hitch (example
script modified from someone's previous post is below). When
linked to a Cygwin program (see script), it runs just as 
expected.

However, if I link the resulting DLL to a MSVC app, it crashes
with a 'Memory could not be "read" ' application error, exactly
as for b18.  If I only comment out the printf statement in my 
DLL, it will run, just as before, implicating the C runtime.

Does anyone have any tips for initialising the C runtime from 
a DLL, in b19?  Is <cygwin32/cygwin_dll.h> relevant?
How can I initialise struct _reent from my DLL?

Any help greatly appreciated,

Matthew Brett

------------------- builddll.sh ---------------------
#! /bin/sh
#  Example Script to compile and link a relocatable DLL
#  Files that make up the DLL = foo.c init.c 
#  (init.c is a housekeeping routine for the DLL
#  The actual library routines are in foo.c)
#  Modified and simplified for b19

# Compile source files:
gcc -c foo.c
gcc -c init.c

# Make .def file:
echo EXPORTS > fooB.def
nm foo.o init.o | grep '^........ [T] _' | sed 's/[^_]*_//' >> fooB.def

# Link DLL.
ld --base-file fooB.base --dll -o fooB.dll foo.o init.o -lcygwin 
-lkernel32 -subsystem windows -e _dll_entry@12 
dlltool --as=as --dllname fooB.dll --def fooB.def --base-file fooB.base 
--output-exp fooB.exp
ld --base-file fooB.base fooB.exp --dll -o fooB.dll foo.o init.o  
-lcygwin -lkernel32 -subsystem windows -e _dll_entry@12 
dlltool --as=as --dllname fooB.dll --def fooB.def --base-file fooB.base 
--output-exp fooB.exp
ld fooB.exp --dll -o fooB.dll foo.o init.o -lcygwin -lkernel32 -subsystem 
windows -e _dll_entry@12 

# Build the fooB.a lib to link to:
dlltool --as=as --dllname fooB.dll --def fooB.def --output-lib fooB.a

# Linking with main
gcc main.c fooB.a -o main.exe

------------------- foo.c ---------------------
#include <stdio.h>

int
doit (int i)
{
     printf("A line of text\n");
     return( 1 );
}

------------------- init.c ---------------------
#include <windows.h> 
#include <stdio.h>
 
extern struct _reent *__imp_reent_data;

BOOL APIENTRY dll_entry(HANDLE hInst, DWORD reason, LPVOID lpReserved)
{
  switch (reason) 
    {
    case DLL_PROCESS_ATTACH:
	_impure_ptr=__imp_reent_data;
      break;
    case DLL_PROCESS_DETACH:
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    }
  return 1;
}
------------------- main.c ---------------------
int
main()
{
        printf("doit(5) returns %d\n", doit(5));
}

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".