如何链接源和标题(cpp vs cu)

时间:2011-12-12 22:01:02

标签: visual-studio-2008 linker cuda

我尝试为外部程序构建一个dll,之前运行良好。但.... 出于某种原因,如果我尝试在Visual Studio 2008专业版Sp1(win7 64位版本)中编译以下内容

intensityRescale<<>>(src_img_in_data,maxValue,minValue,1);

我会收到错误:

1>..\inte.cpp(37) : error C2059: syntax error : '<'

所以我在某处读到了这个必须在.cu文件中,然后我尝试了以下内容:

在“inte.cpp”中,我有:

void inte( DM::Image img, float maxValue, float minValue )
{
#include "inte.h"
#include "Source1.h"
// Some stuff to get the pointer (float * img_data) //WORKS

intensityRescalec(img_data, maxValue, minValue,1);
}

在“inte.h”中我只有:

void inte(DM::Image, float, float );

然后我创建了一个.cu文件“Source1.cu”:

#include "Source1.h"

__global__ void intensityRescale(float *image, float maxValu, float minValu, int typ)
{
const int tid = (blockIdx.y*MNBLOCKX + blockIdx.x)*blockDim.x + threadIdx.x;

    if(tid < MNX0*MNY0*MNZ0)
{   
    if(typ>0)       
        image[tid] = (image[tid] - minValu)/(maxValu-minValu);
    else
        image[tid] = image[tid]*(maxValu-minValu) + minValu;

}
}
 void intensityRescalec(float *mimage, float mmaxValue, float mminValue,int mType)
{

dim3 Mnblocks;
Mnblocks.x = MNBLOCKX;
Mnblocks.y =  ((1 + (MNX0*MNY0*MNZ0 - 1)/MNTHREAD_PER_BLOCK) - 1) / MNBLOCKX + 1; 

intensityRescale<<<Mnblocks, MNTHREAD_PER_BLOCK>>>(mimage, mmaxValue,mminValue,     1);
}

然后在“Source1.h”中:

#ifndef _Source1_h_INCLUDED__
#define _Source1_h_INCLUDED__


#include "cuda.h"
#include <cutil_inline.h>
#include <cublas.h>

#define MNBLOCKX 1024
#define MNX0 1024
#define MNY0 1024
#define MNZ0 1
#define MNBLOCKX 1024
#define MNTHREAD_PER_BLOCK 256
void intensityRescalec(float * da, float d, float f , int g);
void intensityRescale(float *image, float maxValu, float minValu, int typ);
#endif

现在,如果我有自定义构建规则cuda64.rules,它会提供以下内容:

1>inte.obj : error LNK2019: unresolved external symbol "void __cdecl          intensityRescalec(float *,float,float,int)" (?intensityRescalec@@YAXPEAMMMH@Z) referenced  in function "void __cdecl inte(class Gatan_Image *,float,float)"  (?inte@@YAXPEAVGatan_Image@@MM@Z)
1>C:\ProgramData\Gatan\DMSDK\ITK\buildcmake\Release\ITK.dll : fatal error LNK1120: 1   unresolved externals

没有规则:

1>C:\ProgramData\Gatan\DMSDK\ITK\buildcmake\Release\ITK.dll : fatal error LNK1169: one or more multiply defined symbols found

我不在其他任何地方使用这些变量,这是什么意思?

此外,我必须在多线程DLL(/ MD)模式下构建它,因为其他一些库 依靠这个。我没有在CUDA 4中找到cutil64D.lib。这是否已被弃用或者我错过了什么。

我已经下载了所有工具包,驱动程序,cuda SDK,buildrules并按照其中的说明进行操作。还尝试了CUDA VS Wizard。

我已经花了好几天! 没什么工作!!!

HELP!

以前我确实设法从CUFFT建立一个fft项目进入dll所以...... 但这并不涉及内核。

非常感谢任何反馈!

2 个答案:

答案 0 :(得分:0)

您的“intensityRescale&lt;&lt;&gt;&gt;(src_img_in_data,maxValue,minValue,1);”尝试从CPP文件调用CUDA内核导致错误(CPP由VisualStudio的编译器编译,该编译器没有“理解”CUDA语法)。您需要在代码中使用另一个层,以便使用C / CPP兼容接口(不涉及任何CUDA语法的接口)将CUDA文件中的函数公开给CPP文件。 看起来你的代码犯了一些大错。您的链接器错误部分是因为您将文件包含在函数定义中。将包含保留在代码文件的顶部。 通过从SDK源构建和运行某些CUDA SDK演示,验证是否已正确设置编译器等。然后看看是否可以使用一些SDK源代码从头开始设置项目。这将确保您知道需要哪些设置,而不必担心代码(只是项目设置)。一旦它工作,请阅读SDK源代码,看看他们如何布置他们的项目(即哪个源在哪些文件中)。

答案 1 :(得分:0)

它奏效了!
当我使用Cmake生成项目时,Source1.cu的目标机器平台由于某种原因x86甚至认为其他一切都是x64。 我怎么能改变这种行为? 运行时库也是[/ MT],即使我在其他地方都有[/ MD]。 所以,如果其他人遇到同样的问题:

1)右键单击自定义构建规则的项目,然后选择CUDA Runtime API构建规则(v4.0)

2)然后右键单击.cu文件获取属性,然后在CUDA runtime API-&gt; Host中,更改目标机器和运行时库

3)对我来说,我也将代码更改为以下

我将“Source1.h”更改为“Source1.cuh”:

#ifndef _Source1_h_
#define _Source1_h_

void intensityRescalec(float *,float,float);

#endif

和“Source1.cu”:

#include "Source1.cuh"

#ifndef _cuda_h_INCLUDED__
#define _cuda_h_INCLUDED__
#include <cuda.h>
#endif

#ifndef _cutil_inline_h_INCLUDED__
#define _cutil_inline_h_INCLUDED__
#include <cutil_inline.h>
#endif

#ifndef _cublas_h_INCLUDED__
#define _cublas_h_INCLUDED__
#include <cublas.h>
#endif


#define MNBLOCKX 1024
#define MNX0 1024
#define MNY0 1024
#define MNZ0 1
#define MNBLOCKX 1024
#define MNTHREAD_PER_BLOCK 256
dim3 Mnblocks;


__global__ void intensityRescale(float *image, float maxValu, float minValu)
{
const int tid = (blockIdx.y*MNBLOCKX + blockIdx.x)*blockDim.x + threadIdx.x;

    if(tid < MNX0*MNY0*MNZ0)
{   
    //if(typ>0)     
        image[tid] = (image[tid] - minValu)/(maxValu-minValu);
    //else
        //image[tid] = image[tid]*(maxValu-minValu) + minValu;

}
}

void intensityRescalec(float *mimage, float mmaxValue, float mminValue)
{

Mnblocks.x = MNBLOCKX;
Mnblocks.y =  ((1 + (MNX0*MNY0*MNZ0 - 1)/MNTHREAD_PER_BLOCK) - 1) / MNBLOCKX + 1; 

intensityRescale<<<Mnblocks, MNTHREAD_PER_BLOCK>>>(mimage, mmaxValue, mminValue);
}

在“Inte.h”中我只有:

void inte( DM_ImageToken, float, float );

在“Inte.cpp”中,对于#include“Source1.cuh”来说,一切都是同样的期望