0

I kinda have the inverse problem as described here: Combining C++ and C - how does #ifdef __cplusplus work?

The whole app is in C code and now I need to add some C++ functions there. But while doing it I get this error:

/tmp/cczmWtaT.o: In function `aocl_utils::_checkError(int, char const*, int, char const*, ...)':
/home/harp/host/../common/src/AOCLUtils/opencl.cpp:245: undefined reference to `cleanup()'
/tmp/ccrmKQaT.o: In function `main':
/home/harp/host/src/main.c:165: undefined reference to `harp_setup()'
/tmp/ccGKataf.o: In function `solver_propagate(solver_t*)':
/home/harp/host/src/solver.c:751: undefined reference to `launch_kernel()'
collect2: error: ld returned 1 exit status

I've tried:

#ifdef __cplusplus
extern "C" {
#endif

<C code>

#ifdef __cplusplus
}
#endif

But it shows the same error.

What I'm doing is including a C++ header in a C file with the extern functions that I need.

Example:

solver.c

#include "HarpBuffers.h"
...

HarpBuffers.h

extern void harp_setup();
extern void setup_buffers(cl_int a, cl_int b, int **h_clause, unsigned int **h_assigns, int **h_target);

extern void launch_kernel();
extern void cleanup();
testin3r
  • 121
  • 1
  • 9
  • 1
    Did you remember to do `extern "C"` in *both* the header file and the source file? – Some programmer dude Feb 17 '18 at 12:35
  • If you code allows it, the simplest solution may be to compile everything as C++ code. – Ilya Popov Feb 17 '18 at 12:39
  • @Someprogrammerdude yes, both in headers and source file. The problem is that I need to call C++ functions inside the C code. – testin3r Feb 17 '18 at 12:52
  • @IlyaPopov yes, but then I get that error. – testin3r Feb 17 '18 at 12:52
  • 1
    You only show this .h file getting included in the C source code. Where extern "C" does not do anything useful. It must be included in the C++ code as well, forgetting to do this produces this linker error. – Hans Passant Feb 17 '18 at 13:17
  • @HansPassant you're saying that all the code should be inside extern "C"? Please, clarify. – testin3r Feb 17 '18 at 14:52
  • No. Your C++ functions must be declared extern "C". In the C++ code. Since you did not post your C++ code, and did not know that it was important that you did, it is the most likely place you got this wrong. – Hans Passant Feb 17 '18 at 14:57

2 Answers2

5

Your function declarations should be inside an extern "C" block, and they must be seen by the C++ compiler before it encounters the functions' definitions.

(The extern "C" is what makes the C++ compiler not mangle the names of functions.
The #ifdef __cplusplus makes code invisible to a C compiler.)

Like this:

HarpBuffers.h:

#ifdef __cplusplus
extern "C" {
#endif

void harp_setup();
void setup_buffers(cl_int a, cl_int b, int **h_clause, unsigned int **h_assigns, int **h_target);

void launch_kernel();
void cleanup();

#ifdef __cplusplus
}
#endif

(Functions have external linkage by default; there's no need to add clutter in the header.)

solver.c:

#include "HarpBuffers.h"
/* Use functions */

HarpBuffers.cpp:

#include "HarpBuffers.h"
// Define functions
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • Thank you for your reply. But I think there's a misunderstading, the harp_setup, launch_kernel, setup_buffers and cleanup are all functions that use C++ code. To clarify, the app is already written in C, and I must use C++. What do I need however is to put C++ code inside one of that app functions. – testin3r Feb 17 '18 at 14:49
  • 1
    @testin3r: The misunderstanding is yours. No matter what language you intended to write in, the moment you compile your code with a C compiler, _it is C code_. You cannot "put C++ code" in a C source file. All these `#ifdef` and `extern` tricks are just for making it easier to move the same file between being C++ and being C. If you want actual C++ code (code that would not be valid in C) into a C source file, you are out of luck. If you just want to port a function that would be logically valid in both languages, then molbdnilo has shown you how to do that. – Lightness Races in Orbit Feb 17 '18 at 15:29
  • @testin3r You're being very unclear. Are the "harp functions" implemented in C++ and intended to be called from C, or do you want to implement them in C but call C++ from them? – molbdnilo Feb 17 '18 at 17:24
1

You are saying that you are adding C++ codes inside C codes but extern "C" is to add C codes inside a C++ application, so that code declared inside that section should not be considered for name mangling to avoid linking error. So declaring extern "C" does not mean anything for a C compiler. Also in your code you have preprocessor directive like #ifdef __cplusplus this preprocessor directive will only considered by a C++ compiler but not a C compiler. Hence your C compiler will simply ignore that section and extern "C" declaration will not be added in the code. Therefore that declaration does not mean anything for a C compiler. It has meaning only for a C++ compiler as a C++ compiler will add that section of codes declared under preprocessor directive #ifdef __cplusplus into the C++ codes during compilation. Please read properly what preprocessor directive means and how compiler do with these directive during compilation. Also read compilation steps. You need to declare that directives for a C++ compiler when you add C codes in C++ codes. Now you have only one option, you have to compile entire codes by a C++ compiler instead of a C compiler.

Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17