Joel DeWitt
Joel DeWitt

Reputation: 1306

Mixing code in C, C++, and Fortran

I've been playing around with mixing code in C, C++, and Fortran. One simple test I have involves a main program in C++ (cppprogram.C):

#include <iostream>
using namespace std;
extern "C" {
  void ffunction_(float *a, float *b);
}

extern "C" {
  void cfunction(float *a, float *b);
}

void cppfunction(float *a, float *b);

int main() {
  float a=1.0, b=2.0;

  cout << "Before running Fortran function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  ffunction_(&a,&b);

  cout << "After running Fortran function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  cout << "Before running C function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  cfunction(&a,&b);

  cout << "After running C function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  cout << "Before running C++ function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  cppfunction(&a,&b);

  cout << "After running C++ function:" << endl;
  cout << "a=" << a << endl;
  cout << "b=" << b << endl;

  return 0;
}

...calling procedures in C, C++, and Fortran:

C (cfunction1.c)

void cfunction(float *a, float *b) {
  *a=7.0;
  *b=8.0;
}

C++ (cppfunction1.C)

extern "C" {
  void cppfunction(float *a, float *b);
}

void cppfunction(float *a, float *b) {
  *a=5.0;
  *b=6.0;
}

Fortran (ffunction.f)

subroutine ffunction(a,b)
a=3.0
b=4.0
end

Here are the commands I use to make the object files and link them together:

g++ -c cppprogram.C
gcc -c cfunction1.c
g++ -c cppfunction1.C
gfortran -c ffunction.f
g++ -o cppprogram cppprogram.o cfunction1.o cppfunction1.o ffunction.o

Here is my error:

cppprogram.o: In function `main':
cppprogram.C:(.text+0x339): undefined reference to `cppfunction(float*, float*)'
collect2: error: ld returned 1 exit status

I know that internally the compiler sometimes wants underscores appended to the file names, but I thought I had taken care of that. This can be determined with the nm command. There is a small mistake somewhere...does anyone see it? Many thanks in advance.

Upvotes: 3

Views: 288

Answers (1)

chmike
chmike

Reputation: 22154

Update:

You declare cppfunction as extern "C" in cppfunction1.C, but in cppprogram.C you don't declare it as extern "C". Since main is C++ you don't need to declare cppfunction as extern "C" in cppfunction1.C unless you want to be able to call it from C or Fortran.

Remove the extern "C" from cppfunction1.C.

Upvotes: 6

Related Questions