Mail Archives: cygwin/2001/11/16/15:58:43
------=_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 -