2013-01-02 108 views
2

我需要从一个纯C功能main()(驻留在main.c中)内调用CUDA C功能foo()(驻留在gpu.cu)。我在此尝试如下图所示:如何在纯C和CUDA C文件中包含头文件?

  • 的main.c(来电):

    #include "gpu.h" 
    int main(); 
    int main() { foo(); } 
    
  • gpu.hfoo()声明):< ---问题就在这里

    extern void foo(); 
    
  • gpu.cufoo()定义):

    #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.cufoo()声明和定义):

    extern "C" void foo(); 
    extern "C" void foo() { ... } 
    

当然,我宁愿使用跨纯C和CUDA c代码的单个头文件,那么在头文件中使用的正确语法是什么(我们是否仍然需要extern "C"即使它是一个C++的东西)?我需要.cuh扩展名吗?

我正在编译和链接使用NVCC只有(即对于纯C和CUDA-C代码)。

非常感谢。

回答

4

你几乎有这个正确的 - 问题在于你如何使用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 

将使preproces sor根据代码是在C或C++环境中编译而发出不同的代码。但是,如果您尝试使用C++编译器编译任何概念上的C代码,则可能会失败。

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