Subject: Re: Troubles with DLL's
From: [email-masked] (Kees van Veen)

19 Feb 1998 16:35:29 -0800
Message-ID: <[email-masked]>
References: <01bd3b03$4cbdf4e0$60040d8d@ROGKOMUN>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="------------F68BC4309E914F266BDA89A3"
To: Gnu win32 <[email-masked]>

This is a multi-part message in MIME format.
--------------F68BC4309E914F266BDA89A3
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

[email-masked] wrote:

> Look, if you care to read this mailing list you will remember that roge=
r
> ([email-masked]) complained in a message sent on Feb 16th that=

> static data is totally messed up when linking dlls.

> Nobody answered that message.

> And that message is only the last one of an unendless series.

> But go on then. I didn't say anything. The linker is O.K., wonderful.

Well, maybe I should've send the message to the list as well. I
apologize.
Kees

Roger Ren=E9 Kommer wrote:
>
> Hi,
> I?m playing around with dll?s, but received several troubles with stati=
c and
> global data defined in the dll.
> In a little less complex situation (only one dll or without the static
> data), the binaries works like expected.
> =

Hi, I've been wrestling with DLL's some time ago and have a script that
does everything for me, including producing relocatable DLL's. I'm
running programs with 5 relocatable DLL's without problems. I'm using
the latest coolview on NT4 SP3 and Windows 95.
 =

I've attached two scripts (all stolen from Makefile.DLLs by Fergus
Henderson, see the Cygnus page):
 =

         umakedll        to produce relocatable DLLs
         getglobals      a script to locate global variables and to
transform them
			 into a function-like macros (the macros should be used by the
programs =

			 or objects that use the global variables, not by the routines in the
DLL - =

			 check the #ifdef libname_DLL)

Furthermore I have trouble with environment variables. I think that's
caused because the umakedll script links with -lc -lcygwin -lkernel -lc,
which get getenv() from libc instead of winsup (coolview version), so
in order to use environment variables from within the DLL I have
redefined, so I do
 =

#ifdef __CYGWIN32__
#define execvp  _execvp
#define execv   _execv
#define execl   _execl
#define system  _system
#define getenv  _getenv
#define putenv  _putenv
#endif /* __CYGWIN32__ */
 =

#endif /* UCYGWIN32_H */
 =

If you want to run on Windows95 you have to adjust the relocation
section with a program called dllfix.exe.
I've included that as well.

Hope this helps,
Kees
--------------F68BC4309E914F266BDA89A3
Content-Type: text/plain; charset=us-ascii; name="umakedll"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="umakedll"

#! /bin/sh
#	Script to compile and link a relocatable DLL
#	For usage see below
#
#	Files that make up the DLL = $* and $DLLENTRY.cc $FIXUP.c.
#	($DLLENTRY.cc and $FIXUP.c are housekeeping routines needed for the DLL.

if [ "$1" = "-g" ]; then DEBUG="-g"; fi
if [ "$1" = "-s" ]; then USRLIBS="$2"; shift; shift; fi

if [ "$4" = "" ]
then
	echo "Usage: `basename $0` [-g] [-s link-opts] dirname libname libsuffix object..."
	exit 1
fi

DIR=$1;
LIB=$2;
LIBSUFFIX=$3;
shift; shift; shift;

SYSLIBS="$USRLIBS -L`dirname \`gcc -print-file-name=libcygwin.a |
	sed -e 's@^\\\\([A-Za-z]\\\\):@//\\\\1@g' -e 's@\\\\\\\\@/@g' \` `
	-lc -lcygwin -lkernel32 -lc"
DLLENTRY=dllentry
FIXUP=dllfixup

# Generate an entry point routine
echo '
#include <stdio.h>
#include <windows.h> 
extern "C" 
{
	extern struct _reent *_impure_ptr;
	extern struct _reent *__imp_reent_data;
	__attribute__((stdcall))
	int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr);
};

int WINAPI dll_entry (HANDLE, DWORD reason, void*)
{
	_impure_ptr=__imp_reent_data;

	switch (reason) 
	{
	case DLL_PROCESS_ATTACH: break;
	case DLL_PROCESS_DETACH: break;
	case DLL_THREAD_ATTACH: break;
	case DLL_THREAD_DETACH: break;
 	}
	return 1;
}
' >$DLLENTRY.cc

# This is needed to terminate the list of import stuff */
# Copied from winsup/dcrt0.cc in the cygwin32 source distribution. */
echo '	asm(".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0");' > $FIXUP.c

# Compile the generated sources
gcc -c $DLLENTRY.cc $FIXUP.c

# Make .def file:
echo EXPORTS > $LIB.def
nm $* $DLLENTRY.o $FIXUP.o |
grep '^........ [BCDRT] _' |
sed 's/[^_]*_//' >> $LIB.def

# Link DLL.

ld $DEBUG --base-file $LIB.base --dll -o $DIR/$LIB.dll_new \
	$DLLENTRY.o $FIXUP.o $* $SYSLIBS -e _dll_entry@12 

dlltool --as=as --dllname $LIB.dll --def $LIB.def \
	--base-file $LIB.base --output-exp $LIB.exp

ld $DEBUG --base-file $LIB.base $LIB.exp --dll -o $DIR/$LIB.dll_new \
	$DLLENTRY.o $FIXUP.o $* $SYSLIBS -e _dll_entry@12 

dlltool --as=as --dllname $LIB.dll --def $LIB.def \
	--base-file $LIB.base --output-exp $LIB.exp

ld $DEBUG $LIB.exp --dll -o $DIR/$LIB.dll_new $DLLENTRY.o $FIXUP.o $* \
	$SYSLIBS -e _dll_entry@12 

dllfix $DIR/$LIB.dll_new >/dev/null 2>&1

# Build the $LIB.a lib to link to:
dlltool --as=as --dllname $LIB.dll --def $LIB.def \
	--output-lib $DIR/$LIB$LIBSUFFIX

if [ -f $DIR/$LIB.dll ]
then
	mv -f $DIR/$LIB.dll $DIR/$LIB.dll_old
fi
mv -f $DIR/$LIB.dll_new $DIR/$LIB.dll

rm -f $DLLENTRY.cc $DLLENTRY.o $FIXUP.c $FIXUP.o \
	$LIB.base $LIB.exp $LIB.def

--------------F68BC4309E914F266BDA89A3
Content-Type: text/plain; charset=us-ascii; name="getglobals"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="getglobals"

if [ "$1" = "" ]
then
	echo Usage: $0 libname
	exit 1
fi

SYM_PREFIX=$1
GUARD_MACRO=${SYM_PREFIX}_GLOBALS_H
DEFINE_DLL_MACRO=${SYM_PREFIX}_DEFINE_DLL
USE_DLL_MACRO=${SYM_PREFIX}_USE_DLL
IMP_MACRO=${SYM_PREFIX}_IMP
GLOBAL_MACRO=${SYM_PREFIX}_GLOBAL
IMPURE_PTR=${SYM_PREFIX}_impure_ptr

echo "
#ifndef ${GUARD_MACRO}
#define ${GUARD_MACRO}
#if defined(__GNUC__) && defined(__CYGWIN32__)
#if defined(${USE_DLL_MACRO})
	#define ${IMP_MACRO}(name)	__imp_##name
	#define ${GLOBAL_MACRO}(name)	(*${IMP_MACRO}(name))
	#include \"${SYM_PREFIX}_globals.h\"
#endif /* ${USE_DLL_MACRO} */
#endif /* __GNUC__ && __CYGWIN32__ */

#endif /* ${GUARD_MACRO} */"	> ${SYM_PREFIX}_dll.h

for sym in ${IMPURE_PTR} \
	`nm $1.a | grep '^........ [BCDR] _' | sed 's/[^_]*_//'`;
do
	echo "#define $sym	${GLOBAL_MACRO}($sym)"
done > ${SYM_PREFIX}_globals.h

--------------F68BC4309E914F266BDA89A3
Content-Type: application/x-gzip; name="dllfix.exe.gz"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="dllfix.exe.gz"

--------------F68BC4309E914F266BDA89A3--

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