我需要在纯C 函数中调用 CUDA C 函数foo()
(驻留在 gpu.cu 中) main()
(驻留在 main.c 中)。我对此的尝试如下所示:
main.c (来电者):
#include "gpu.h"
int main();
int main() { foo(); }
gpu.h (foo()
声明):< ---问题
extern void foo();
gpu.cu (foo()
定义):
#include "gpu.h"
extern "C" void foo() { ... }
我收到错误:
gpu.cu(2): error: linkage specification is incompatible with previous "foo"
gpu.h(1): here
但是,如果不使用标题文件,则以下可以工作:
main.c (来电者):
void foo();
int main();
int main() { foo(); }
gpu.cu (foo()
声明和定义):
extern "C" void foo();
extern "C" void foo() { ... }
当然,我更喜欢在纯C和CUDA c代码中使用单个头文件,因此在头文件中使用的正确语法是什么(即使它是C ++,我们仍然需要extern "C"
事情)?我需要.cuh扩展吗?
我正在使用仅限NVCC 进行编译和链接(即纯C和CUDA-C代码)。
非常感谢。
答案 0 :(得分:5)
你几乎有这个正确 - 问题在于你如何使用gpu.h
。工具链报告的冲突正在发生,因为gpu.cu
中包含的头文件声明foo()
将具有C ++链接,但该定义具有C链接。
基本问题是您尝试将gpu.h
用作C和C ++标头。这通常不是一个好主意,但可以使它工作。一种方法是确定它是一个C头文件并修改C ++代码将其视为一个,所以在gpu.cu
执行此操作:
extern "C" {
#include "gpu.h"
}
extern "C" void foo() { ... };
另一种方法是修改gpu.h
,使其行为不同,具体取决于它是由C编译器还是C ++编译器包含,如下所示:
#ifdef __cplusplus
extern "C" {
#endif
extern void foo();
#ifdef __cplusplus
}
#endif
或
#ifdef __cplusplus
extern "C" void foo();
#else
void foo();
#endif
将使预处理器发出不同的代码,具体取决于代码是在C或C ++环境中编译。但是,如果您尝试使用C ++编译器编译任何一个名义上的C代码,则可能会失败。
你如何选择解决这个问题可能在很大程度上取决于代码的真实结构,我猜这并不像你所描述的那么简单。