A Moron's Guide to Using Microsoft DLL's when Compiling Cygwin or Mingw Programs


Background

I do my software development using either Cygwin and Mingw and have so far avoided the use of Microsoft Visual C. None-the-less, for all its faults, Microsoft provides some usefull subroutines in its DLLs. It is usually trivial to use the subroutines in Microsoft DLLs in your Cygwin or Mingw programs because someone from one of those groups has provided an import library and all you have to do is include that when you compile. For example, to use Microsoft's Winsock library with your Cygwin or Mingw program, simply add "-lwsock32" to the gcc compile command line.

The problem

This tutorial explains how to use the subroutines in a Microsoft DLL when no one has yet provided the necessary import library.

The solution

So far as I know, there is no way to use the subroutines in a Microsoft DLL without an import library. If no one has provided an import library, it is up to you to create one.

An import library is like your typical static (.a) library and tells the compiler how to access the Microsoft subroutine.

In order to make the import library you will need a .def file, which lists the exportable routines that the DLL has.

First, copy the relevant DLL to your working directory.

If you are a masochist, one way of getting the information necessary to make a .def file is to bring up a Windows command prompt, chdir to your working directory, and execute the Microsoft command

          DUMPBIN /EXPORTS RASDLG.DLL > list.  

The file "list" will give all the exportable functions.

An easier way to create the .def file is to use the program "pexports" to generate the .def file.

The format for using pexports is

       pexports RASDLG.DLL | sed 's/^_//' > rasdlg.def

In my case, the sed part did nothing because there were no underlines in the exportables.

The background for what we have to do next can be found in Colin Peters' excellent tutorial. If you go to this URL, choose "An Introduction to (mostly) GNU C and C++ Programming Tools", and finally "DLL Import Library Tool".

Proceeding as suggested by Colin Peters' tutorial, the .def file created by pexports needs to be edited by hand.

In the case we are discussing, I was interested in using the RasDialDlgA function in RASDLG.DLL. When I compiled my program without the import library, which I did not yet have, the error message from gcc was "undefined reference to RasDialDlgA@16". The .def file created from the Microsoft DLL has "RasDialDlgA" because that is what the Microsoft name is, but it does not have the "@16" at the end. It is necessary to add the "@16" by hand so the GNU compiler will be happy. An interesting question to ponder, "If the damn compiler KNOWS its supposed to be '@16', why do you have to type it in"?

After editing by hand, my .def file looked like

LIBRARY RASDLG.dll
EXPORTS
DwTerminalDlg
GetRasDialOutProtocols
RasAutodialDisableDlgA
RasAutodialDisableDlgW
RasAutodialQueryDlgA
RasAutodialQueryDlgW
RasDialDlgA@16
RasDialDlgW
RasEntryDlgA
..., etc.

Once I make the import library from this file, I only will be able to call the RasDialDlgA subroutine from RASDLG.DLL, unless I take the time to figure out and edit in the appropriate "@nn" for the other subroutines that need it.

We are now ready to make our import library using dlltool. If it was necessary to add an "@nn" to keep gcc happy, (it isn't always necessary) be sure to add the option -k to the end of the dlltool command line in order to tell the compiler or linker that only gcc, not the Microsoft DLL, uses the "@nn". If you didn't add an "@nn", leave out the "-k" or you will get a compile time error.

The format for this for RasDlg is

    dlltool --input-def rasdlg.def  --dllname RASDLG.DLL --output-lib librasdlg.a -k

Then do either

     cp librasdlg.a /usr/lib/w32api
     ranlib /usr/lib/w32api/librasdlg.a  

for Cygwin, or

for Mingw.

     cp librasdlg.a /Mingw/lib
     ranlib /Mingw/lib/librasdlg.a  

Finally,

      gcc prog.c -o prog -lrasdlg

will allow the program "prog" to use the RasDialDlgA subroutine that is in Microsoft's RASDLG.DLL.

Further information about pexports

You may download a copy of pexports-0.43 from my site.

I found that pexports would often crash when it attempted to extract exports from Functions (whatever that means), so I created a WinZipped patch that causes the program to avoid executing this part. The program seems to work, but if the section bypassed does anything important, clearly this doesn't get done with the patched version. In other words, my patch bypasses the problem, it does not fix it.

Check out our shareware.
Read our other Moron guide.


Emmes Technologies.
Updated May 4, 2006.

valid html 4.01!