如何在纯C和CUDA C文件中包含头文件?

时间:2013-01-02 00:34:28

标签: c cuda header-files

我需要在纯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代码)。

非常感谢。

1 个答案:

答案 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代码,则可能会失败。

你如何选择解决这个问题可能在很大程度上取决于代码的真实结构,我猜这并不像你所描述的那么简单。