2013-01-02 137 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代碼,則可能會失敗。

你如何選擇解決這個問題可能很大程度上取決於你的代碼的真實結構,我猜測它並不像你所描述的那麼簡單。