我在构建程序时遇到了一些麻烦。我正在使用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(¶ms);
}
我觉得我在这里遗漏了一些非常基本的东西,但是我无法弄明白,所以任何帮助都会很棒!
答案 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汇编对象语言中的一些代码。