Chapter 3. Interfaces

This chapter contains the following major sections:

Using Other Language Libraries from C++ Programs

Most C++ programmers want to be able to link with object files and libraries written in languages other than C++, especially C. In order to do so, you must include in your programs declarations for the functions you wish to call. In most cases you can do this by simply including appropriate header files with the #include directive. For the standard C header files supplied by Silicon Graphics, using #include is all you need to do. For example, if you are going to use C standard I/O, you must include the following line in your source or header file:

#include <stdio.h>

To use the Graphics Library™, you must include the following line in your source or header file:

#include <gl/gl.h>

C Function Declarations in C++ Programs

If you want to call C functions from a C++ program, either directly or by file inclusion, you must be sure the C++ program contains correctly prototypes declarations for the functions, and that the function declarations are recognizable by the C++ compiler as declaring functions whose definitions are in C. These steps are necessary because C++ normally encodes (mangles) function names to support overloading. The real name of a function declared in a C++ program as void printf(char*, ...), for example, is printf__FPce. The printf function in libc.so, however, is just called printf.

To allow a C++ program to call functions written in C, C++ provides linkage specifications. To use the standard printf function, for example, you could write the following code:

extern "C" {
   void printf(char *, ...);
}

You can include this code in the C++ source file that calls printf, or in a header file that is included by the source file. The use of extern “C” tells the translator that the function linkage should be done according to the conventions used by the C programming language, in particular, with no mangling. A function name declared in this way is said to have C linkage.

If you want to adapt an existing C header file or create a header file of your own containing C function declarations, and you want to be able to include it in either C or C++ programs, you can use the fact that __cplusplus (with two underscores preceding it) is always defined for C++ compilations and is always undefined otherwise. Thus, you can enclose C function declarations with the following code:

#ifdef __cplusplus
extern "C" {
#endif

and

#ifdef __cplusplus
}
#endif

This scheme is used to create the Silicon Graphics C header files.

Using C++ Libraries From C Programs

You may want to use libraries created by C++ from programs written in C. One way to do this is to create interface functions written in C++ but declared as having C linkage so they can be called from C programs. Suppose, for example, that you have a C++ library that implements a symbol table class. It might have a class declaration that looks like the sample from table.h below:

class symtab {
 ...
public:
 symtab();
 void add_name(char *);
 int lookup(char *);
 ...
};

You might create an interface header file (called interface.h, for example) that looks like the sample below:

extern "C" {
 void init_table(void);
 void add_name(char *);
 int lookup(char *);
 …
}

You would also create an interface program (called interface.c, for example) that looks like the sample below:

#include "table.h" // class declaration for symtab
#include "interface.h"
static symtab * stab;
void init_table(void)
{
 stab = new symtab;
}

void add_name(char *name)
{
 stab->add_name(name);
}

int lookup(char * name)
{
 return stab->lookup(name);
}

A problem often encountered in using C++ libraries from C programs is that global objects defined in the library are not initialized if the main program is not in C++. To overcome this problem, link your program using CC instead of cc or ld. Linking using CC ensures that the linked executable will have its C++ global objects correctly initialized on program start-up.

If your program (or DSO) includes C++ object files that have global objects that need to be constructed at program start-up, link your program (or DSO) using CC. (For information on DSOs, see “Dynamic Shared Objects” in the MIPS Compiling and Performance Tuning Guide.)