4

I'm using Linux and I have the following files:

main.c, main.h
fileA.c, fileA.h
fileB.cpp, fileB.h

The function F1() is declared in fileB.h and defined in fileB.cpp. I need to use the function in fileA.c, and so I declared the function as

extern void F1();

in fileA.c.

However, during compilation, I got the error

fileA.c: (.text+0x2b7): undefined reference to `F1'

What is wrong?

Thank you.

ETA: Thanks to the answers I've received, I now have the following:

In fileA.h, I have

#include fileB.h
#include main.h

#ifdef __cplusplus
extern "C" 
#endif
void F1();

In fileA.c, I have

#include fileA.h

In fileB.h, I have

extern "C" void F1();

In fileB.cpp, I have

#include "fileB.h"

extern "C" void F1()
{ }

However, I now have the error

fileB.h: error: expected identifier or '(' before string constant
Rayne
  • 14,247
  • 16
  • 42
  • 59

5 Answers5

19

If you're really compiling fileA.c as C, not C++, then you need to make sure that the function has the proper, C-compatible linkage.

You can do this with a special case of the extern keyword. Both at declaration and definition:

extern "C" void F1();
extern "C" void F1() {}

Otherwise the C linker will be looking for a function that only really exists with some mangled C++ name, and an unsupported calling convention. :)

Unfortunately, whilst this is what you have to do in C++, the syntax isn't valid in C. You must make the extern visible only to the C++ code.

So, with some preprocessor magic:

#ifdef __cplusplus
extern "C"
#endif
void F1();

Not entirely pretty, but it's the price you pay for sharing a header between code of two languages.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • So now I have extern "C" void F1(); and extern "C" void F1() {} in my fileB.h and fileB.cpp respectively, and also extern "C" void F1(); in fileA.c. But during compilation, I get the errors "fileB.h: error: expected identifier or "(" before string constant", "fileA.c: error: expected identifier or "(" before string constant", and also "fileA.c: warning: implicit declaration of function "F1"." – Rayne Jun 21 '11 at 10:08
  • @Tomalak: I'm still getting some errors. See my edit of my original entry. – Rayne Jun 21 '11 at 10:38
  • @Rayne: It's `__cplusplus`, not `__cpluplus`. And the problem is: your C can see the function declaration twice. One from the header (where you haven't used the macro: this is _the_ place you should be doing it, as this is the code that's shared between languages), and one from `fileA.c`, where you shouldn't be writing a declaration at all. – Lightness Races in Orbit Jun 21 '11 at 10:38
  • @Tomalak: I've made the changes (please see edit in original entry), but am still getting the "expected identifier" error. I don't have the "implicit declaration" error anymore. – Rayne Jun 21 '11 at 10:53
  • @Rayne: Why does `fileB.h` declare the header? Your C code can _still_ see a line of `extern "C"`. Think about what includes go where. You should declare the function _in **one** header_ and define it _in **one** source file_. The header can be included in many places, including (thanks to our macro trick) in a C source file. – Lightness Races in Orbit Jun 21 '11 at 10:55
  • Thanks for your help! I can finally compile and link the program now. – Rayne Jun 22 '11 at 02:15
5

To be able to call a c++ function from c source code you neeed to give the appropriate linkage specification.

The format for specifying linkage specification is

extern "type_of_Linkage" <function_name>

So in your case, you should be using:

extern "C" void F1();
Alok Save
  • 202,538
  • 53
  • 430
  • 533
4

perhaps, use

extern "C" void F1();
mattn
  • 7,571
  • 30
  • 54
2

fileA.c can't include fileB.h (via fileA.h) because the C compiler doesn't know what extern "C" means, so it complains that it sees an identifier before a string. don't try to include fileB.h in fileA.c or fileA.h. its not needed

dmh2000
  • 683
  • 3
  • 7
-1

fileA.c needs to also include fileA.h I believe.

Xedecimal
  • 3,153
  • 1
  • 19
  • 22