Subject: Re: Another problem with DLL's
From: [email-masked] (John Cerney)

20 Mar 1997 14:44:49 -0800
Approved: [email-masked]
Distribution: cygnus
Message-ID: <[email-masked]>
Reply-To: John Cerney <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7Bit
X-Mailer: BeyondMail for Windows/Professional 2.3
Original-To: " Ismael  Jurado" <[email-masked]>
X-BeyondMail-Priority: 1
Conversation-ID: <[email-masked]>
Original-Cc: [email-masked]
X-Receipt-From-Agent: true
Original-Sender: [email-masked]

>I've got a problem with DLL's...
>
>Folowing the instruccions of the home page of Cygnus, everything works
>OK when I link the DLL with my executable but... if you try to load the
>library indirectly via LoadLibrary(), it returns an HRESULT of 0
>
>Someone knows how to solve this or is just a bug?

I'm not sure what is wrong with your code, but I know this does work. Here is a
simple example of loading a DLL at runtime using LoadLibraryEx calls. This
compiles and links fine on both win95 and winNT.

  Note: This uses the same 3-pass ld/dlltool process that Cygnus used to build
    cygwin.dll. I just adapted it from the cygwin.dll makefile included in the
     source distribution. You might be able to get by with a procedure that
uses
     only 1 or 2 passes. However, I have had problems with executables not
running
     on both winNT and win95 when a 1 or 2 pass procedure is used. I believe
the
     3-pass approach to be the safest.

-John

***** File main2.c *******
// Main file to try linking with a DLL under gnuwin32

// Updated to load dll at runtime (as opposed to loadtime), using
//   win32 dll load functions
#include <stdio.h>
#include <windows.h>

int (*doitptr)(int); // pointer to the doit routine

int
main()
{

	char filename[]="foo.dll";
	HINSTANCE dllhandle;   // handle to the dll
	
	// Load the dll into memory:
	if( (dllhandle = LoadLibraryExA(filename, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH )) 
		== NULL){
		printf("Error, Could not load %s\n",filename);
		exit(0);
	}

	doitptr = GetProcAddress(dllhandle, "doit");
	if( doitptr == NULL){
		printf("Error, Could not load doit symbol\n");	
	} 
        printf("doit(5) returns %d\n", (*doitptr)(5));
       
}
***** File foo.c *****
// Test file to check out building DLLs with gnuwin32
//  This uses printf from the std lib

#include <stdio.h>

//* function declarations:  ***
int doit (int i);

int
doit (int i)
{

     printf("In foo.c inside of doit with printf\n");  

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

# Build the foo.a lib to link to: (not really needed for run-time loading)
dlltool --as=as --dllname foo.dll --def foo.def --output-lib foo.a

# Linking with main
gcc -g main2.c -o main2.exe
 
-
For help on using this list, send a message to
"[email-masked]" with one line of text: "help".