The pro*c precompiler and the Oracle Call C++ Interface (OCI) are essential tools for interacting with Oracle databases. If you've programmed with pro*c or OCI on Windows before, you're probably familiar with one of the various compilers it works with, such as Microsoft Visual C/C++ or Borland C/C++. However, pro*c and OCI libraries may also be used with the GNU MinGW compiler.
I've written several programs using pro*c that had to run on both UNIX and Windows operating systems. It's easier to port a program from GNU GCC on UNIX to MinGW than it is to port a UNIX program to many other Windows compilers. With the addition of some #ifdefs, I've had no problems using the same files for UNIX machines and MinGW on Windows. MinGW is useful if you want to program with pro*c or OCI and don't already own a compiler. You can try MinGW simply by downloading it from http://www.mingw.org/. It's easy to install. All you need to do is unzip the files and set your path to point to the bin directory.
So how do you get pro*c or OCI to work with MinGW? On Windows, DLLs are supplied by Oracle for using the pro*c and OCI libraries. There are also .lib files and include files supplied for each of the popular compilers from Microsoft and Borland. To get pro*c or OCI working with MinGW, you'll need the DLLs, include files, and the equivalent of the library file (.a or .lib), but in a format MinGW can read. One way to create the library file equivalent is by using the program pexports. There are other methods to create a library file for a DLL listed in the MinGW FAQ located at the MinGW web site (http://www.mingw.org/). The pexports technique works just as well for other nonstandard compilers. As long as you have a program that can create the .lib or .a file format for that specific compiler from a DLL format, you can access the functions in the DLL with your code.
For which DLLs do you need to create library files? It depends on what version of Oracle you're running. For my projects using Oracle 8.0.5, I worked with sqllib80.dll for pro*c and oci.dll for OCI. For another project that was run using an earlier version of Oracle, Version 7.3.3, the sqllib18.dll was used for pro*c work and ociw32.dll was used for OCI.
For pro*c programs, create your .pc file as you would with any compiler. Run pro*c on it. Compile the output of the pro*c precompiler. When you do so, use the -I option with GCC to let the MinGW compiler know the directory where the necessary Oracle include files (such as sqlca.h and oraca.h) are located. Link the object along with the .a file and any other files needed to create the final executable. The pro*c precompiler created .c files for me. If you're linking with other files in C++ instead of C, remember to add the appropriate 'extern "C"' syntax when working with these files. For OCI programming, write your program as you normally would. Compile and link the files along with the .a file. You'll need to give the appropriate path for the Oracle include files when compiling.
I used the examples that came with pro*c and OCI as the basis for writing my code. I found the pro*c and OCI libraries very helpful in creating CGI programs that displayed tables and charts on the Web, based on information in an Oracle database. There were very few differences in my source files between the UNIX and Windows versions. Basically, all I had to add were some #ifdefs for standard C include files that required different naming conventions on UNIX and Windows (such as memory.h on Windows and mem.h on UNIX). The rest of my code was exactly the same across platforms.
DLL Linking
A simple example of how to link with a DLL when there is no library file (.a or .lib) and no def file follows. This example uses the MinGW compiler (I tested this with Version 2.95.2) and assumes you have a version of it already installed.
Download pexports. You can do so from the location indicated in the MinGW FAQ at the MinGW web site (http://www.mingw.org/) or from http://www.distasis.com/intercomp/code/pexports.zip. Pexports is a free tool and is copyrighted under the GNU public license.
First, create a DLL for testing. Create the files shown in Listing 1. Then use these MinGW commands to create a DLL and an executable.
gcc -c hello.c gcc -c -DBUILD_DLL dllfunc.c dllwrap --output-lib=libhello.a -- dllname=hello.dll --driver-name=gcc dllfunc.o gcc -o hello.exe hello.o -L./ -lhello
Run the program "hello," and you should see the usual greeting.
Now that you have the DLL and executable created, you can try building an executable from only the DLL without the library and def files available. Move the executable file and library file (.a) to another directory. You can also move the dllfunc.o and dllfunc.c files. You no longer need them. With just the DLL file, you can recreate a library file using the following commands:
pexports -o hello.dll > hello2.def dlltool --def hello2.def --dllname hello.dll --output-lib libhello2.a
You can now rebuild and run the executable with the new library file as follows:
gcc -o hello.exe hello.o -L./ -lhello2
When you execute the program "hello," you should see the same greeting. This technique also works with Oracle's DLLs or other DLLs.
If you're interested in cross-platform development with Oracle or you want to try out the pro*c or OCI libraries but need a good compiler, give MinGW a try. I've also seen OTL (the Oracle Template Library, based on OCI) work successfully with MinGW. There's even a MinGW mailing list if you get stuck and need help from other programmers.
Laura Michaels is a senior software engineer at INTERCOMP, creator of entertainment, hobby, and custom software. She has written articles for C/C++ Users Journal, Windows Developer Magazine, and Dr. Dobb's Journal.