3

純粋なC関数(main.cにある)内からCUDA C関数foo()gpu.cuにある)を呼び出す必要があります。これに対する私の試みを以下に示します。main()

  • 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のみを使用してコンパイルおよびリンクしています(つまり、pure-CコードとCUDA-Cコードの両方)。

どうもありがとう。

4

1 に答える 1

5

あなたはほとんどこれを正しく持っています-問題はあなたがどのように使っているかにありますgpu.h。ツールチェーンによって報告された競合は、に含まれるヘッダーファイルがC ++リンケージを持つことをgpu.cu宣言しているために発生していfoo()ますが、定義にはCリンケージがあります。

基本的な問題はgpu.h、CヘッダーとC++ヘッダーの両方として使用しようとしていることです。これは通常は良い考えではありませんが、機能させることができます。1つのアプローチは、それがCヘッダーファイルであると判断し、C ++コードを変更して1つとして扱うことです。そのため、次のようにgpu.cuします。

extern "C" {
#include "gpu.h"
}

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

gpu.hもう1つは、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コードのいずれかをコンパイルしようとすると、これは失敗する可能性があります。

これをどのように修正するかは、おそらくコードの実際の構造に大きく依存します。これは、あなたが説明したほど単純ではないと私は推測しています。

于 2013-01-02T08:05:15.040 に答える