Subject: Can't use gnuwin DLL with non gnuwin program
From: [email-masked] (Matthew Brett)

24 Jan 1998 22:06:08 -0800
Message-ID: <Pine.SUN.3.91.980125020341.6096A.cygnus.gnu-win32@magpie>
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Transfer-Encoding: 8bit
To: [email-masked]
Cc: [email-masked]

Dear All,

I am having great difficulty linking a gnuwin dll which uses the 
cygwin libraries with programs not compiled with gnuwin.  I imagine 
I am doing something stupid, but would be very grateful for any help.  
Below is an example set of files that show that (on my x86 NT4 sp3 
system anyway) you can compile and link a dll to a gnuwin program 
without difficulty, but if you attempt to link the same program 
compiled in VC++ to the DLL compiled with gnuwin, it crashes.  I 
think this may not be restricted to VC++ because I have had crashes 
with similar DLLs from within other programs, in particular from 
DLLs built for matlab.

Is it possible that it is only DLLs that call the Cygwin DLL that cause 
the trouble?  A DLL with only some simple maths code causes no 
crash.

I have looked through previous messages, but couldn't find much to 
help me.  I tried a suggestion from Sergey Okhapkin of adding 
__main() to the DLL_PROCESS_ATTACH section of the DLL admin 
code, but this had no effect.  I do need the Unix functionality of 
Cygwin, so I imagine that I won't be able to use mingw32

I'm using the latest coolview dll/library and b18.

Below are instructions, simple files which will (I think) replicate my 
problem, if you have VC++.  Obviously I've borrowed most of the stuff 
below from John Cerney's "Building a relocatable DLL" message

Many thanks for any advice,

Matthew Brett

To replicate (maybe) my problem: 
Save the files below to their specified names in some directory
In bash type:
	makedll.sh main vcdll
	main

You should get:
	Still running here
	dll_func returns 42

Then try:
	cmd /c vclink main vcdll
	main

You may get a window with:
	The instruction at @~"£ referenced memory at $&^%@~ etc

However, if you create the DLL within VC++, using the following 
lines added to the .bat file:

cl -c %DLLFILE%.c
link %DLLFILE%.obj /dll /export:dll_func /OUT:%DLLFILE%.dll

then there is no crash when running main.exe.  And the gnuwin main 
program will happily link to the DLL created in VC++.

--------------> main.c <-------------
// Main file to try linking with a DLL from gnuwin32
#include <stdio.h>

int dll_func();

int main()
{
	printf("dll_func returns %d\n", dll_func());
	return(1);
}
--------------> vcdll.c <-------------
/* vcdll.c */
#include <stdio.h>

int dll_func()
{
	/* it may break down here */
	printf("Still running here\n");
      return( 42 );
}
--------------> fixup.c <-------------
/* This is needed to terminate the list of inport 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");
--------------> init.cc <-------------
/* init.cc */
#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;
}
--------------> makedll.sh <-------------
#! /bin/sh
#  Script to compile and link a relocatable DLL
#  Source routines for the DLL = defined in first argument to script.

# first argument is file name for main program (for linking to DLL)
# second argument is file name for compiling to DLL
main=${1%.[Cc]}
croot=${2%.[Cc]}

# ***Fill in your path to libcygwin.a here (with no trailing slash)***
LIBPATH=/gnuwin32/b18/H-i386-cygwin32/i386-cygwin32/lib

# Compile source files:
gcc -c ${croot}.c
gcc -c init.cc
gcc -c fixup.c

# Make .def file:
echo EXPORTS > ${croot}.def
nm ${croot}.o init.o fixup.o | grep '^........ [T] _' | sed 's/[^_]*_//' 
>> 
${croot}.def

# Link DLL.
ld --base-file ${croot}.base --dll -o ${croot}.dll ${croot}.o init.o 
fixup.o $LIBPATH/libcygwin.a -e _dll_entry@12 
dlltool --as=as --dllname ${croot}.dll --def ${croot}.def --base-file 
${croot}.base --output-exp ${croot}.exp
ld --base-file ${croot}.base ${croot}.exp --dll -o ${croot}.dll 
${croot}.o init.o fixup.o $LIBPATH/libcygwin.a -e _dll_entry@12 
dlltool --as=as --dllname ${croot}.dll --def ${croot}.def --base-file 
${croot}.base --output-exp ${croot}.exp
ld ${croot}.exp --dll -o ${croot}.dll ${croot}.o init.o fixup.o 
$LIBPATH/libcygwin.a -e _dll_entry@12 

# Build the .a lib to link to:
dlltool --as=as --dllname ${croot}.dll --def ${croot}.def --output-lib 
${croot}.a

# Linking with main
gcc ${main}.c ${croot}.a -o ${main}.exe
--------------> vclink.bat <-------------
@echo off
rem BAT file to link GCC dll with VC++ program
rem call with file name roots of main c file, and dll file name
rem e.g vclink main vcdll (where main.c and vcdll.dll are the files 
required)

set MAINFILE=%1%
set DLLFILE=%2%

rem Set the file locations below if you need to
set MSVC_ROOT=%MSVC_ROOT%
set PATH=%MSVC_ROOT%\BIN;%PATH%
set INCLUDE=%MSVC_ROOT%\INCLUDE;%INCLUDE%
set LIB=%MSVC_ROOT%\LIB;%LIB%

rem Compiler parameters
cl -c %MAINFILE%.c

rem Library creation command
echo LIBRARY %DLLFILE%.dll > temp.def
type %DLLFILE%.def >> temp.def
lib /def:\temp\temp.def /machine:ix86 /OUT:temp.lib

rem Linker parameters
link %MAINFILE%.obj temp.lib /out:%MAINFILE%.exe

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