Using Scientific Software Tools' DLPortIO Universal Port Driver with MinGW32 (or Cygwin.)


Background

This page describes how to directly access PC I/O ports from C code compiled using the MinGW32 port of the gcc compiler, running under Windows NT or Windows 2000.

I have written a lot of C code to load and run software on an old LSIC30 ISA DSP card. The original code was developed using the excellent DJGPP2 port of the gcc compiler under DOS, and latterly under Windows 98.  Neither DOS nor Windows 98 places any restriction on access to PC hardware ports by the user code.

As Windows 98 is now officially obsolete, and therefore no longer supported by Microsoft for security updates, I decided to upgrade to Windows 2000, which does prevent direct I/O port access by user code.  To work around this, I have used the SST DLPortIO  universal driver, which allows port access via an API that uses a kernel driver.  Many thanks to SST for an outstanding (free!) product that we have used on several occasions, and is also used by many companies to do the same job.

For simplicity in porting code that already worked with a gcc compiler, I chose the MinGW32 port of gcc.

Dlportio comes with examples and a DLL library to use the driver with Microsoft and Borland C/C++ compilers.  No direct mention is made of the MinGW32 compiler. There are two ways to link in a Microsoft-created DLL such as DLPORTIO.dll:

or:

Example Code

try.c is a very simple program that writes to the standard LPT1 parallel printer port on a PC.  It is written using the outportb() function that writes a byte to a specified port.  outportb()is implemented by the libraries of several DOS-based compilers such as Turbo C and DJGPP, the DOS port of the gcc compiler.

fakeio.c contains a mapping of inportw/b() and outportw/b() C calls using DlPortIO API calls.

Before you follow either of the following recipes, it is of course assumed that you have installed the DLPortIO driver.


The Easy Way

This is discussed in the MinGW32 FAQ.

Type the following at the msys command prompt to create an executable:

gcc -c try.c
gcc -c fakeio.c
gcc -o try.exe try.o fakeio.o DLPORTIO.lib
(note that there is no '-l' to identify DLPORTIO.lib as a library.)

DLPORTIO.lib referred to above is the standard (MSVC) import library from the DLPortIO package.


The Hard Way

I use the latest MinGW32 distribution (v3.1.0-1) with the associated msys shell. The formally correct way to use a Microsoft-originated DLL such as DLPORTIO.dll with your own (gcc) C code under MinGW32, is to create an import library in gcc *.a format.  The following is largely based on A moron's Guide to Using Microsoft DLLs when Compiling Cygwin or MinGW Programs, a very useful document!

I suppose that the above "easy" way of doing things might not work for some DLLs, hence my decision to include the following.

Please note that this same procedure may be applied to make a MinGW32 import library for any DLL that comes with an associated MS inport library.

(1)    Using the msys shell, use pexports to create a first  draft of the definition file:

         pexports DLPORTIO.dll | sed '/_//' > DLPORTIO.def

This produces the following DLPORTIO.def:

  LIBRARY DlPortIO.dll
 EXPORTS
 DlPortReadPortBufferUchar
 DlPortReadPortBufferUlong
 DlPortReadPortBufferUshort
 DlPortReadPortUchar
 DlPortReadPortUlong
 DlPortReadPortUshort
 DlPortWritePortBufferUchar
 DlPortWritePortBufferUlong
 DlPortWritePortBufferUshort
 DlPortWritePortUchar
 DlPortWritePortUlong
 DlPortWritePortUshort


(2)    It is necessary to manually add information about the size of data passed on the stack by each API call, by performing the following mods (deduced by examining a "strings" dump of the MS dlportio.lib import library):

  LIBRARY DlPortIO.dll
 EXPORTS
 DlPortReadPortBufferUchar@12
 DlPortReadPortBufferUlong@12
 DlPortReadPortBufferUshort@12
 DlPortReadPortUchar@4
 DlPortReadPortUlong@4
 DlPortReadPortUshort@4
 DlPortWritePortBufferUchar@12
 DlPortWritePortBufferUlong@12
 DlPortWritePortBufferUshort@12
 DlPortWritePortUchar@8
 DlPortWritePortUlong@8
 DlPortWritePortUshort@8
(3) This may then be turned into a MINGW32 import library as follows:
dlltool --input-def DLPORTIO.def --dllname DLPORTIO.dll --output-lib libDLPORTIO.a -k
cp libDLPORTIO.a /mingw/lib
ranlib /mingw/lib/libDLPORTIO.a
Finally, to use the DLL, e.g.:
gcc -c try.c
gcc -c fakeio.c
gcc -o try.exe try.o fakeio.o -lDLPORTIO
Here, -lDLPORTIO refers to the newly-created libDLPORTIO.a import library in MinGW32 format.


I am very interested to hear of other users of DLPortIO.dll with MinGW32 code.  Send me an Email if this page has been useful!


Ronan Scaife, School of Electronic Engineering, Dublin City University, Dublin 9, IRELAND
 mailto:scaifer AT eeng DOTT dcu DOTT ie
last revision:    October 13th 2003