Reputation: 10156
I need to call a CUDA C function foo()
(residing in gpu.cu) from within a pure C function main()
(residing in main.c). My attempt at this is illustrated below:
main.c (caller):
#include "gpu.h"
int main();
int main() { foo(); }
gpu.h (foo()
declaration): <--- problem here
extern void foo();
gpu.cu (foo()
definition):
#include "gpu.h"
extern "C" void foo() { ... }
I get the error:
gpu.cu(2): error: linkage specification is incompatible with previous "foo"
gpu.h(1): here
However, without using header files the following does work:
main.c (caller):
void foo();
int main();
int main() { foo(); }
gpu.cu (foo()
declaration and definition):
extern "C" void foo();
extern "C" void foo() { ... }
Of course, I would prefer using a single header file across both pure C and CUDA c code, so what is the correct syntax to use in the header file (do we still need extern "C"
even though it's a C++ thing)? Do I need a .cuh extension?
I am compiling and linking using NVCC only (i.e. for both pure-C and CUDA-C code).
Many thanks.
Upvotes: 3
Views: 6653
Reputation: 72339
You almost have this correct - the problem is in how you are using gpu.h
. The conflict reported by the toolchain is happening because the header file included in gpu.cu
declares that foo()
will have C++ linkage, but then the definition has C linkage.
The basic problem is that you are trying to use gpu.h
as both a C and C++ header. This is usually not a good idea, but it can be made to work. One approach is to decide that it is a C header file and modify the C++ code to treat it as one, so in gpu.cu
do this:
extern "C" {
#include "gpu.h"
}
extern "C" void foo() { ... };
The other would be to modify gpu.h
so that its behaviour is different depending on whether it is being included by a C compiler or a C++ compiler, so something like:
#ifdef __cplusplus
extern "C" {
#endif
extern void foo();
#ifdef __cplusplus
}
#endif
or
#ifdef __cplusplus
extern "C" void foo();
#else
void foo();
#endif
would make the preprocessor emit different code depending on whether the code is being compiled in a C or C++ environment. This may, however, fail if you try and compile any of your notionally C code using a C++ compiler.
How you choose to fix this will probably depend heavily on the real structure of your code, which I am guessing is not as simple as you have described.
Upvotes: 5