1

C++ コードを C に変換しましたが、Makefile も変更しようとしています。私はこれを持っていました:

g++ -fPIC -o bin/linux/release/gpu_md5 cuda_md5.c cuda_md5_cpu.c obj/release/cuda_md5_gpu.cu.o 
-L/usr/local/cuda/lib64 -L../../lib64 
-L../../common/lib64/linux -L/opt/cuda/NVIDIA_CUDA_SDK/lib64 -lcudart     
-L/usr/local/cuda/lib64 -L../../lib64 
-L../../common/lib64/linux -L/opt/cuda/NVIDIA_CUDA_SDK/lib64

私の知る限り、g ++をgccに変更するだけでうまくいくはずですが、そうではありません。gcc は、cuda_md5.c で呼び出している cuda_md5_cpu.c の関数を見つけることができないようです (PS: cuda_md5.c に cuda_md5_cpu.c を含めていません):

/tmp/ccKdDJiq.o: In function `cuda_compute_md5s':
cuda_md5.c:(.text+0x201): undefined reference to `init_constants'
cuda_md5.c:(.text+0x2e2): undefined reference to `execute_kernel'
collect2: ld returned 1 exit status

なにが問題ですか?g++ から gcc に変更しました。

4

1 に答える 1

2

obj/release/cuda_md5_gpu.cu.o(再コンパイルしていないようです) が C++ コンパイラでコンパイルされている可能性が非常に高いため、名前マングリングによって変更されたシンボル名が含まれている可能性が非常に高いと思います。

名前マングリングは、C++ コンパイラが使用する手法で、異なる関数に同じ名前を付けてパラメータの型を変える (オーバーロード) ことを許可します。オーバーロードが許可されていないため、C コンパイラはこれを行う必要がありません。

言い換えると、init_constants(int,float);は C コンパイラによって単純に に変形されるかもしれません_init_constantsが、C++ コンパイラを使用すると、または_init_constants_$$_IntFloatと区別するためにのようなものが得られます。init_constants(int,double)init_constants(void)

cuda_md5.cそのため、C でコンパイルされたものと C++ でコンパイルされたものをリンクしようとするリンカーはobj/release/cuda_md5_gpu.cu.o、関数名を一致させることができません。

これが、C++ コードでよく見られる理由ですextern "C" { ... }。C 規則を使用して関数名 (およびその他のもの) をリンカーにエクスポートし、C と C++ コードを一緒にリンクできるようにします。

于 2012-10-14T05:33:09.493 に答える