delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/11/16/15:58:43

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
From: "Ralf Habacker" <Ralf DOT Habacker AT freenet DOT de>
To: "Cygwin" <cygwin AT sources DOT redhat DOT com>
Subject: RE: Linking to commercial dll's
Date: Fri, 16 Nov 2001 22:02:36 +0100
Message-ID: <000901c16ee2$05054420$fa6607d5@BRAMSCHE>
MIME-Version: 1.0
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0
In-Reply-To: <OF8B6193A7.B4A10832-ON85256AFF.004E05C7@ipaper.com>
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400
Importance: Normal

------=_NextPart_000_000A_01C16EEA.66C9AC20
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

> -----Ursprüngliche Nachricht-----
> Von: cygwin-owner AT sources DOT redhat DOT com
> [mailto:cygwin-owner AT sources DOT redhat DOT com]Im Auftrag von David Westbury
> Gesendet am: Donnerstag, 15. November 2001 17:11
> An: cygwin AT cygwin DOT com
> Betreff: Linking to commercial dll's
>
> I'm attempting to link a C program that I've written to a commercial dll
> (non-MS) using gcc in cygwin. I've read about everything I can find about
> dll's but I can't seem to make my program access functions in the dll
> correctly. My program compiles/links without errors using gcc, and even
> runs correctly to some extent. Some functions work, others don't. The
> functions that don't work seem to corrupt memory as evidenced by changes in
> random variable values. This occurs even when the function return status
> indicates success. The commercial package provides a ".dll" file, a ".lib"
> file, and a ".h" file. These are obviously intended for use in a Windows
> programming environment. I would appreciate if someone knowledgable would
> tell me what steps would typically be required to link a program to a well
> established commercial dll. For example, what might a typical gcc string
> look like? Do gcc switches like "-L", and "-l" apply? Should I be linking
> to the .dll or the .lib file?
>
> Dll's seem to be an especially difficult subject in cygwin, requiring
> detailed knowlege of the MS way of doing things. Are dll's not
> standardized? Is a "cookbook" approach to dll linking not possible? The
> issue seems to be a steep hill for an average working programmer, like me,
> to climb. This limits the usefulness of cygwin as a programming environment
> for me.
>
> BTW, is cygwin intended for MS programmers wanting to explore the Unix
> world or is it of more interest to Unix programmers who, like me, have an
> occasional need to run Unix programs on Windows?  Programmers coming from
> Unix typically won't know much about dll's so a little more introductory
> documentation or pointers to such material would seem appropriate for the
> cygwin site. I've been to the bookstores and haven't found much help there,
> even in Windows programming texts. Apparently dll's simply work correctly
> in Windows and require little explanation. One text did say something that
> seemed to indicate that I should be linking against the .lib file as it
> contains pointers into the .dll fine. This doesn't work for me at all
> however.
>
> Here's the gcc string I'm using that results in a partially working
> executable:
>
> gcc -g myprog.c  -o myprog  /<path to commercial dll>/filename.dll
>
> Any help or pointers to information would be greatly appreciated.
>
1. For a deeply explanation of the windows dll format look at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwbgen/html/ms
dn_peeringpe.asp.

2. You have to create a ld compatible import library. You can use the tools
impgen and dlltool for doing this. impgen comes from the libtool package and is
appended to this mail. dlltool is a part of the basic cygwin.

Here is an example for a dll named 'libxslt.dll':

1. compile the tool impgen with the appended source file

	gcc -o impgen impgen.c
	cp ./impgen /usr/local/bin


2. create a file with all exported symbols from the dll (it's called 'def'
file).

	impgen libxslt.dll >libxslt.def


3. create an import library with this def file

	dlltool -d libxslt.def -l libxslt.a


4. Now you can link your app with the dll (in truth with the import library)
	Note:
	There may be some compiling problems with
	the include file from your dll in case of
	redefined symbols or compiler syntay.
	It may be nessesary to patch this.

	gcc -o yourapp yourapp.c -L. -lxslt

	Note2:
	You can verify using the import library with the -Wl,--verbose flag in you
command line.

	gcc -o yourapp yourapp.c -L. -lxslt -Wl,--verbose

	Then you see some lines with

	...
	attempt to open /usr/lib/w32api/libkernel32.dll.a failed
	attempt to open /usr/lib/w32api/libkernel32.a succeeded
	...

	which shows, that you are linking the .a file, not the dll.


Perhaps that helps

PS: To the cygwin cracks: If I have written something wrong, please correct
this.

Regards

Ralf Habacker


------=_NextPart_000_000A_01C16EEA.66C9AC20
Content-Type: application/octet-stream;
	name="impgen.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="impgen.c"

 /* impgen.c starts here */
 /*   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.

  This file is part of GNU libtool.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */

 #include <stdio.h>		/* for printf() */
 #include <unistd.h>		/* for open(), lseek(), read() */
 #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
 #include <string.h>		/* for strdup() */
 
 /* O_BINARY isn't required (or even defined sometimes) under Unix */
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
 
 static unsigned int
 pe_get16 (fd, offset)
      int fd;
      int offset;
 {
   unsigned char b[2];
   lseek (fd, offset, SEEK_SET);
   read (fd, b, 2);
   return b[0] + (b[1]<<8);
 }

 static unsigned int
 pe_get32 (fd, offset)
     int fd;
     int offset;
 {
   unsigned char b[4];
   lseek (fd, offset, SEEK_SET);
   read (fd, b, 4);
   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
 }

 static unsigned int
 pe_as32 (ptr)
      void *ptr;
 {
   unsigned char *b = ptr;
   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
 }

 int
 main (argc, argv)
     int argc;
     char *argv[];
 {
     int dll;
     unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
     unsigned long export_rva, export_size, nsections, secptr, expptr;
     unsigned long name_rvas, nexp;
     unsigned char *expdata, *erva;
     char *filename, *dll_name;

     filename = argv[1];

     dll = open(filename, O_RDONLY|O_BINARY);
     if (dll < 1)
 	return 1;

     dll_name = filename;

     for (i=0; filename[i]; i++)
 	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
 	    dll_name = filename + i +1;

     pe_header_offset = pe_get32 (dll, 0x3c);
     opthdr_ofs = pe_header_offset + 4 + 20;
     num_entries = pe_get32 (dll, opthdr_ofs + 92);

     if (num_entries < 1) /* no exports */
 	return 1;

     export_rva = pe_get32 (dll, opthdr_ofs + 96);
     export_size = pe_get32 (dll, opthdr_ofs + 100);
     nsections = pe_get16 (dll, pe_header_offset + 4 +2);
     secptr = (pe_header_offset + 4 + 20 +
 	      pe_get16 (dll, pe_header_offset + 4 + 16));

     expptr = 0;
     for (i = 0; i < nsections; i++)
     {
 	char sname[8];
 	unsigned long secptr1 = secptr + 40 * i;
 	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
 	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
 	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
 	lseek(dll, secptr1, SEEK_SET);
 	read(dll, sname, 8);
 	if (vaddr <= export_rva && vaddr+vsize > export_rva)
 	{
 	    expptr = fptr + (export_rva - vaddr);
 	    if (export_rva + export_size > vaddr + vsize)
 		export_size = vsize - (export_rva - vaddr);
 	    break;
 	}
     }

     expdata = (unsigned char*)malloc(export_size);
     lseek (dll, expptr, SEEK_SET);
     read (dll, expdata, export_size);
     erva = expdata - export_rva;

     nexp = pe_as32 (expdata+24);
     name_rvas = pe_as32 (expdata+32);

     printf ("EXPORTS\n");
     for (i = 0; i<nexp; i++)
     {
 	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
 	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
     }

     return 0;
 }
 /* impgen.c ends here */


------=_NextPart_000_000A_01C16EEA.66C9AC20
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
------=_NextPart_000_000A_01C16EEA.66C9AC20--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019