From: mbrett AT magpie DOT rpms DOT ac DOT uk (Matthew Brett) Subject: Can't use gnuwin DLL with non gnuwin program 24 Jan 1998 22:06:08 -0800 Message-ID: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Content-Transfer-Encoding: 8bit To: gnu-win32 AT cygnus DOT com Cc: mbrett AT magpie DOT rpms DOT ac DOT uk 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 int dll_func(); int main() { printf("dll_func returns %d\n", dll_func()); return(1); } --------------> vcdll.c <------------- /* vcdll.c */ #include 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 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 AT 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 AT 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 AT 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 "gnu-win32-request AT cygnus DOT com" with one line of text: "help".