在VS2008中构建Cuda程序的麻烦:LNK2019

时间:2010-06-30 15:59:17

标签: c++ visual-studio-2008 build cuda lnk2019

我在构建程序时遇到了一些麻烦。我正在使用Visual Studio 2008处理Windows 7专业版32位。我有Cuda SDK,我的项目设置了所有cudart.lib等链接。我的问题是当我尝试构建我的项目时它返回以下错误:

  

1> crowdSim.obj:错误LNK2019:   未解决的外部符号   函数“protected:void __thiscall”中引用了_setParameters   人群:: _创建(INT)”   (?_create @围观@@ IAEXH @ Z)   1> crowdSim.obj:错误LNK2019:   未解析的外部符号_mapBuffer   在函数中引用“protected:   void __thiscall Crowd :: _ create(int)“   (?_create @围观@@ IAEXH @ Z)   1> crowdSim.obj:错误LNK2019:   未解决的外部符号   _allocToDevice在函数“protected:void __thiscall中引用   人群:: _创建(INT)”   (?_create @围观@@ IAEXH @ Z)   1> crowdSim.obj:错误LNK2019:   未解决的外部符号   _registerBuffer在函数“protected:void __thiscall中引用   人群:: _创建(INT)”   (?_create @围观@@ IAEXH @ Z)   1> ../../ bin / win32 / Debug / crowd.exe:   致命错误LNK1120:4未解决   的外部

似乎我的问题在于如何设置我的“allocToDevice”,“mapBuffer”,“setParameters”和“registerBuffer”方法,因为如果我发表评论,我可以构建项目没问题。

我已经在以下文件中定义了方法:

crowdSim.cuh:

    extern "C"
{
    void checkCUDAError(const char *msg);

    void setParameters(SimParams *hostParams);

    void registerBuffer(uint vbo);

    void allocToDevice(void **ptr, int memSize);

    void mapBuffer(void **ptr, uint vbo);
}

crowdSim.cu:

#include <cstdlib.h>
#include <cstdio.h>
#include <string.h>

#include <cuda_gl_interop.h>

// includes, kernels
#include "crowd_kernel.cu"

extern "C"
{
void checkCUDAError(const char *msg)
{
    cudaError_t err = cudaGetLastError();
    if( cudaSuccess != err) 
    {
        fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
        exit(-1);
    }                         
}

void setParameters(SimParams *hostParams)
{
    // copy parameters to constant memory
    cudaMemcpyToSymbol(params, hostParams, sizeof(SimParams));
}

void registerBuffer(uint vbo)
{
    cudaGLRegisterBufferObject(vbo);
}



void allocToDevice(void **ptr, size_t memSize)
{
    cudaMalloc(ptr, memSize);
}

void mapBuffer(void **ptr, uint vbo)
{
    cudaGLMapBufferObject(ptr, vbo);
}
} //extern "C"

并且只能从crowdSim.cpp的“Crowd”类中的_create方法调用它们:

#include <math.h>
#include <memory.h>
#include <cstdio>
#include <cstdlib>
#include <GL/glew.h>

#include "crowdSim.h"
#include "crowdSim.cuh"
#include "crowd_kernel.cuh"

Crowd::Crowd(uint crowdSize) :
    //numP(crowdSize),
    hPos(0),
    hVel(0),
    dPosIn(0),
    dVelIn(0),
    dPosOut(0),
    dVelOut(0)
    {
        params.numBodies = crowdSize;
        _create(crowdSize);
    }

Crowd::~Crowd()
    {
        //_remove();
        crowdSize = 0;
    }

uint
Crowd::newVBO(uint size)
{
    GLuint vbo;
 //   glGenBuffers(1, &vbo);
 //   glBindBuffer(GL_ARRAY_BUFFER, vbo);
 //   glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
 //   glBindBuffer(GL_ARRAY_BUFFER, 0);
    return vbo;
}

void
Crowd::_create(int numPeople)
{
    crowdSize = numPeople;

    unsigned int memSize = sizeof(float) * crowdSize * 4;

    hPos = new float[crowdSize*4];
    hVel = new float[crowdSize*4];

    hPos = (float*) malloc(memSize);
    hVel = (float*) malloc(memSize);

    posVbo = newVBO(memSize);

    registerBuffer(posVbo);

    allocToDevice((void**) &dPosIn, memSize);
    allocToDevice((void**) &dPosOut, memSize);
    allocToDevice((void**) &dVelIn, memSize);
    allocToDevice((void**) &dVelOut, memSize);

    mapBuffer((void**)&dPosVbo, posVbo);

    setParameters(&params);

}

我觉得我在这里遗漏了一些非常基本的东西,但是我无法弄明白,所以任何帮助都会很棒!

3 个答案:

答案 0 :(得分:2)

您是否添加了cuda.rules文件以使Visual Studio能够识别.cu扩展名? cuda.rules教会VS如何处理.cu以便它将被编译和链接。有关设置的详细信息,请参阅this post

顺便说一句,如果你在头文件中的函数的声明(原型)中有extern "C",那么你就不应该在定义(实现)上使用它。它可能会使您的代码更整洁 - 通常我根本不使用extern "C"

答案 1 :(得分:1)

我最近遇到了从C ++代码调用CUDA函数的问题。我决定使用extern并在线学习一些教程。

在阅读完代码后,有一件事我做了不同的事情。我没有做cuda文件的包含(crowdsim.cuh),而是在我的C ++代码中声明了该函数。我在我的C ++文件中重写了extern声明,并编译了代码,这次它起作用了。

这是我提到的教程。希望它有所帮助

http://codereflect.com/2008/09/29/how-to-call-cuda-programs-from-a-cc-application/

答案 2 :(得分:0)

当然,只有当你没有混合的c / c ++和Cuda文件时才会这样,在这种情况下,NVCC可以生成一些对象用于常规链接以及GPU汇编对象语言中的一些代码。