Lesson of 18 February 2011¶
Example of linking with foreign language (and decoration)
A Fortran routine making simple addition
File add.f
1 subroutine add( a, b, c )
2 real*8 a(*), b(*), c(*)
3 do i=1,3
4 c(i) = a(i) + b(i)
5 end do
6 return
7 end
A simple C++ code with use external routine
File testDecoration.cc
1// to compile on unix/OSX use
2// g++ -c testDecoration.cc (for generation of testDecoration.o)
3// g95 -c add.f (for generation of test.o a fortran routine)
4// g++ testDecoration.o add.o -o test
5// ./test (to run)
6//
7
8#include <iostream>
9
10using namespace std ;
11
12typedef struct {
13 double x, y, z ;
14} Point3D ;
15
16// routine 1
17void
18add( Point3D const * const a, // pointer to a structure, pointer non modificable
19 Point3D const * const b,
20 Point3D * const c ) {
21 c -> x = a -> x + b -> x ;
22 c -> y = a -> y + b -> y ;
23 c -> z = a -> z + b -> z ;
24}
25
26// routine 2
27void
28add( Point3D const & a,
29 Point3D const & b,
30 Point3D & c ) {
31 c.x = a.x + b.x ;
32 c.y = a.y + b.y ;
33 c.z = a.z + b.z ;
34}
35
36#define F77NAME(A) A##_
37
38// routine 3
39// make a prototype of the external routine
40extern "C" void F77NAME(add)( double * a, double * b, double * c ) ;
41
42int
43main( int argc, char const * argv []) {
44 double a[3] = {1,2,3} ;
45 double b[3] = {3,4,5} ;
46 double c[3] ;
47
48 F77NAME(add)( a, b, c ) ; // only routine 3 match the prototype
49
50 cout << "c = [ " << c[0] << ", " << c[1] << ", " << c[2] << " ]\n" ;
51
52 return 0 ;
53}
The C decoration A simple code which use an external
printOnTerminal
C routine
File testDecoration2.cc
1// to compile on unix/OSX use
2// g++ -c testDecoration2.cc testDecoration2b.c -o test (for generation of testDecoration.o)
3// ./test (to run)
4//
5
6#include <iostream>
7
8using namespace std ;
9
10// declare a prototype for a C++ routine
11void printOnTerminal( char const msg[] ) ;
12
13int
14main( int argc, char const * argv []) {
15 char theMessage[] = "Ciao Mamma!\n" ;
16 printOnTerminal( theMessage ) ;
17 return 0 ;
18}
A C code which define _Z15printOnTerminalPKc
. The
code link (on GNU compiler) because the name fit the
decoration of C++:
File testDecoration2b.c
1// to compile on unix/OSX use
2// g++ -c testDecoration2.cc
3// gcc -c testDecoration2b.c
4// g++ testDecoration2.o testDecoration2b.o -o test (for generation of testDecoration.o)
5// ./test (to run)
6//
7
8#include <stdio.h>
9
10void
11_Z15printOnTerminalPKc( char const msg[] ) {
12 printf(msg) ;
13}
Another example of Fortran linking A simple code
which use an external print
Fortran routine
File testFortranLink.cc
1// to compile on unix/OSX use
2// g++ -c testDecoration.cc (for generation of testDecoration.o)
3// g95 -c test.f (for generation of test.o a fortran routine)
4// g++ testDecoration.o test.o -o test
5// ./test (to run)
6//
7
8#include <cstdlib>
9#include <cstring>
10
11using namespace std ;
12
13#define F77NAME(A) A##_
14
15// make a prototype of the external routine
16extern "C" void F77NAME(print)( char const * msg, int * value, unsigned long msgLen ) ;
17
18int
19main( int argc, char const * argv []) {
20 char msg[] = "I am a C message!" ;
21 int value = 199 ;
22 F77NAME(print)( msg, &value, strlen(msg) ) ;
23 return 0 ;
24}
The fortran routine for which a parameter is a variable length string:
File print.f
1 subroutine print( msg, value )
2 integer value
3 character*(*) msg
4 print *,msg,value
5 return
6 end