==============================================================================
C-Scene Issue #2
Interfacing C code with C++.
Name: Brent York
Handle: The Dragon	(ThaDragon on IRC)
Email: york@nbnet.nb.ca
Affils: Coder for Nuclear Winter Entertainment
	Coder for Spheringer technologies.
	Coder for Henry and York Development    "Development with thought."
        Editor of Cscene Magazine
	Organizer of the OS Developers Information Network (ODIN).
==============================================================================

	C++ is a wonderful language, and most if not all things that you can
write in C you can write in C++ as well. Unfortunately however there 
comes a time where you come accross some of your old C code that you 
wrote way back when that you dont want to have to rewrite or restructure 
for your current code.

	Seeing as to how one big plus of programming properly is code 
reusability which is a great thing and speeds up development times. 
However one of the main problems between multilanguage interfacing is 
that no two languages ever call functions or pass parameters the same way.

	This of course can be a PITA. This document (I hope) will show 
you how to solve this problem for multilanguage programming using C and C++ 
together.




===========
The Dilemma
===========
	
	The main problem (so I hear) with interfacing with C++ is that it 
mangles function names. The reasons for this are things such as overloaded
functions, destructors and constructors etc. We wont go into the guts of 
writing a C++ compiler here because it probably isn't needed. 

	All you need to realise is that C doesn't mangle function names 
and therefore C++ (expecting the mangling) cant find them. This causes a 
problem not necessarily when compiling but CERTAINLY when linking.



==============================================
Extern, a declaration of an external "object".
==============================================

	So now we have great fun, and learn a way to declare externals. 
You might ask what extern has to do with interfacing C with C++, and we 
wont get into it just yet (hay I have to fill my article quota ;}), but 
we will in the next section.		

	Extern is used for declaring external data or functions, and can
be used in a block format to encompass many things at once or in a single 
line format to only encompass one thing.

	Then the compiler sees extern it allows the use of the external 
reference in your code, but makes the linker look for the external at 
linking time.

	This is a great boon for things like global variables (yuck), but is
rarely used to declare functions external because they are implicitly 
external. That is to say the compiler knows that they are extern.

	However, this isn't the case as you will soon see, when interfacing
C++ with C. (Wow, a rhyme =})

	The syntax of extern is:

extern ["C"] [{] Things to declare external [[}] || [;]]

All things in []'s are optional, except for the || (or obviously) which 
means that you either have to close off your { with a } if you used that, 
or you can use ; in a single line.

Example of a single line extern declaration

extern int myGVar;

Example of a multi line extern declaration
extern {
  int myGVar;
  int yourGVar;
  int everyBodysGVar;
}



==============================
The cure for function mangling
==============================

	The cure of course as you may have noticed is the "C" optional 
in the extern declaration's syntax. In the .h file you include in your 
C++ all functions and global data you want to use in your C++ program 
should be declared extern "C".

	 That is to say that youll have to have two .h files, one for 
your C source (which should NOT be extern "C") and one for the C++ source 
that holds the function prototypes and global variables for the C source, 
all declared extern "C".

An example follows:

--------------------------use_c.c----------------------------
#include <stdio.h>
#include "use_c_c.h"			/* C header for C file */

void printme(void) {
  printf("Hello from C!\n");
}

-------------------------use_c_c.h----------------------------
/* C header for use_c.c */

#ifndef __CPP_USE_C_C_HDR__
#define __CPP_USE_C_C_HDR__
void printme(void);
#endif
-------------------------use_cpp.hh----------------------------
// C++ header for use_c.c so we can use it with our c++ program

#ifndef __CPP_USE_C_CPP_HDR__
#define __CPP_USE_C_CPP_HDR__
extern "C" void printme(void);
#endif
-------------------------use_cpp.cc----------------------------
// C++ main function that uses use_c's printme() function.
#include <stdio.h>
#include "use_cpp.h"

int main(void) {
  printme();
  return 0;
}
---------------------------------------------------------------


Of course, this is a simple example, but the same holds true for global 
data, and all functions you must use. to save space and make it more 
readable you can use a blocked extern. But ALL THINGS that you must 
access from the .c file such as functions and data MUST be declared extern.

Compile the above program and run it with prettymuch any compiler and 
youll get the intended output.

Note however that you MUST compile the .c file with a C compiler, not a 
C++ compiler, and you MUST compile the .cc file with a .cc compiler.


===============
Finishing words
===============

	All in all interfacing C with C++ isn't that hard, infact its the 
easiest task that one can come accross with multilanguage programming.
All you have to remember is the extern keyword and all is set.

And now you have the knowlege to take it even further and be able to 
reuse your C code in your C programs without changes, isn't that great?

Have fun, and most of all, contribute!

The Dragon

You can download a zipfile of the source in this document here.


C Scene Official Web Site : http://cscene.oftheinter.net
C Scene Official Email : cscene@mindless.com
This page is Copyright © 1997 By C Scene. All Rights Reserved