14

I am quite new to C and C++. But I have some C++ functions which I need to call them from C. I made an example of what I need to do


main.c:

#include "example.h"      
#include <stdio.h>

int main(){   
    helloWorld();
    return 0;
}

example.h:

 #ifndef HEADER_FILE
 #define HEADER_FILE

 #ifdef __cplusplus
     extern "C" {
 #endif
         void helloWorld();
 #ifdef __cplusplus
     }
 #endif

 #endif

example.cpp:

#include <iostream.h>

void helloWorld(){
    printf("hello from CPP");
} 

It just doesn't work. I still receive the error of undefined reference to _helloWorld in my main.c. Where is the the problem?

gpoo
  • 8,408
  • 3
  • 38
  • 53
user1702375
  • 141
  • 1
  • 1
  • 4
  • 2
    The standard C++ header `` doesn't have a `.h`. Your compiler may have `` as an extension, but its contents are unpredictable. `printf` for instance usually comes from `` – MSalters Sep 27 '12 at 06:55
  • When you don't control the C++ library: http://stackoverflow.com/questions/2744181/how-to-call-c-function-from-c – Ciro Santilli OurBigBook.com May 29 '15 at 10:10

2 Answers2

15

Short answer:

example.cpp should include example.h.

Longer answer:

When you declare a function in C++, it has C++ linkage and calling conventions. (In practice the most important feature of this is name mangling - the process by which a C++ compiler alters the name of a symbol so that you can have functions with the same name that vary in parameter types.) extern "C" (present in your header file) is your way around it - it specifies that this is a C function, callable from C code, eg. not mangled.

You have extern "C" in your header file, which is a good start, but your C++ file is not including it and does not have extern "C" in the declaration, so it doesn't know to compile it as a C function.

asveikau
  • 39,039
  • 2
  • 53
  • 68
  • 1
    @MSalters - In this case it is needed (or: it is my recommended one-line fix) and it is why the link is failing, I am in the process of typing up an explanation. – asveikau Sep 27 '12 at 06:54
  • Missing `extern "C"` is indeed the correct answer, but legally that may also appear in the .cpp – MSalters Sep 27 '12 at 06:57
  • @MSalters - This is true and I know that, but I was going for a succinct recommendation and followed by an elaborative explanation ... That way they can take the quick answer if they need it, but also keep reading to see how one gets to this. – asveikau Sep 27 '12 at 07:03
  • @asveikau +1, but this part can be worded better: *…it doesn't know to compile it as a C function* (and i know from the rest of your answer that you know it has to do with naming, not compiling). – justin Sep 27 '12 at 07:11
3

the extern "C" tells C++ that the declared function has to use the C ABI (Application Binary interface), hence, whether the language is C or C++, your void HelloWorld() is always seen externally as it is C.

But you implemented it in the cpp file like it is a C++ one, C is not aware of.

You have to make the prototype of HelloWorld coherent for both C and C++, so the cpp file should declare it as extern "C" void Helloworld() { /*your code here*/ }, or simply, #include "example.h" from example.cpp, so that, before implementing it, the compiler already knows it has to follow the C convention.

Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
  • You are absolutely right. When I write the same program but instead write my main as a "main.cpp" and will add extern "c" before the helloWorld() or add the "example.h" to it, it works. But still when I add the "example.h" or extern "C" in my "main.c" file, it just doesn't work. – user1702375 Sep 27 '12 at 12:45
  • @user1702375 - You don't want "`extern "C"` to appear in a `.c` file. That's why people put `#ifdef __cplusplus` around it in headers. – asveikau Sep 27 '12 at 21:29
  • right, maybe I just explained in wrong words. what I meant was that when I have my main as a cpp code "main.cpp" this rule works. But when I have my main as a c code "main.c" it still doesn't work. Although I have added the example.h in my "example.cpp" as well. – user1702375 Oct 01 '12 at 12:37