【问题标题】:Trouble with building Cuda programme in VS2008: LNK2019在 VS2008 中构建 Cuda 程序的问题:LNK2019
【发布时间】:2010-06-30 15:59:16
【问题描述】:

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

1>crowdSim.obj:错误 LNK2019: 未解析的外部符号 函数“protected: void __thiscall”中引用的 _setParameters 人群::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj:错误 LNK2019: 未解析的外部符号_mapBuffer 在函数“受保护: void __thiscall Crowd::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj:错误 LNK2019: 未解析的外部符号 函数“protected: void __thiscall”中引用的 _allocToDevice 人群::_create(int)" (?_create@Crowd@@IAEXH@Z) 1>crowdSim.obj:错误 LNK2019: 未解析的外部符号 _registerBuffer 在函数“protected: void __thiscall”中引用 人群::_create(int)" (?_create@Crowd@@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);

}

我觉得我在这里遗漏了一些非常基本的东西,但我不知道是什么,所以任何帮助都会很棒!

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 感谢汤姆的快速回复。我已经按照你的帖子在 Visual Studio 中设置了项目,尽管有一些我找不到的可选部分,例如我无法在我的项目属性中看到 C/C++ -> General 以将 CUDA 包含文件添加到搜索路径。我已经包含了 cuda.rules 和运行时库,所以我仍然卡住了。
    • 暂无关于找不到 C/C++ 的部分 -> 常规。显然它就在那里。
    • 如果您的项目中只有 .cu 文件,那么 Visual Studio 将不会直接调用 C/C++ 编译器 (cl.exe),因此项目属性中的 C/C++ 类别将不存在。不过没关系,因为那里的设置都不相关!因此,如果您只有 .cu 文件,请忽略 C/C++ 设置。
    【解决方案2】:

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

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

    这是我提到的教程。希望对你有帮助

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

    【讨论】:

    • 关于你找不到 C/C++ 的部分......当我有一个只包含 .cu 文件的项目时,曾经发生在我身上。我不确定,但这可能是原因。
    • 查看我对关于 .cu only 项目的其他答案的评论。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-16
      • 2021-11-16
      • 1970-01-01
      • 2019-10-17
      • 1970-01-01
      相关资源
      最近更新 更多