Making and Using Libraries

4. Vendor Libraries

Before you create your own libraries, you have probably paid attention to the issues of naming and linkage conventions for your routines. When you use someone else's library, you may need to know exactly what names and linkage conventions they have used for the functions in their library.

To find this out, there is a utility called dumpbin which comes with the Microsoft C Compiler that you can use on a static or import library. To see what functions are available to the linker from square.lib:

dumpbin /LINKERMEMBER:1 square.lib

gives, among other things, a list of public symbols. For an import library produced by the Intel Fortran compiler from square.f, the list might look like:

17E __IMPORT_DESCRIPTOR_square
3A6 __NULL_IMPORT_DESCRIPTOR
4DC ⌂square_NULL_THUNK_DATA
62E _SQUARE
62E __imp__SQUARE
For an import library produced by the Microsoft C compiler,

dumpbin /LINKERMEMBER:1 libsquare.lib

gives a single public symbol:

A6 _square

Subroutines and functions in Windows are preceded by an underscore, but notice that the two import libraries have three different versions of square: _square, _SQUARE, and _SQUARE@4. The linker is case-sensitive, so a program that calls function square must tell the linker to expect a form of the routine that is present in the import library presented to it.

Using the import library from the C compiler with a C program that has the prototype:

int square(int);

is no problem. Likewise, calling the Fortran square from a Fortran program will work fine.

Crossing over requires a little more work. To use the C version, one could include the line:

Idec$ ATTRIBUTES C :: square

in the interface block for square. This changes from the default stdcall linkage convention to the C linkage convention and also changes the default name from uppercase to lowercase.

To call the FORTRAN library function from C, two things must be done: (1) the FORTRAN compiler makes the name uppercase by default, so

#define square SQUARE

and (2) FORTRAN calls by reference, so change the prototype to:

int square (int *);

and make the call

y = square(&x);

For example, the MPI/Pro libraries come in three forms:

mpipro.lib Mixed case names and C linkage only
mpipro_stdc.lib Upper case names and stdcall linkage only
mpipro_cdec.lib Lower case names and C linkage only
The mpipro.lib works with typical C programs as long as the user pays attention to the MPI naming conventions.  The mpipro_cdec.lib could be used with the Intel Fortran compiler if one choses lowercase (non-default) for external names.