2015-05-19 52 views
1

我试图创建一个框架,以便能够在多个游戏引擎中使用CUDA代码。为了能够与所有想要的引擎进行通信,框架由两个主要部分组成。一个Lib和一个DLL。 Lib包含所有功能(CUDA和常规C++),并且DLL可以作为从Lib调用函数的桥梁。CUDA链接错误(Lib到Dll)

现在,一切都运行oke,直到我已经包含一个.cu文件。当我建设,我发现了以下错误:

Error 3 error LNK2019: unresolved external symbol _Add2And7 referenced in function "public: void __thiscall PerceptorHost::UpdatePerceptorHost(void)" ([email protected]@@QAEXXZ) D:\_Professional\DAE_Research\2_Projects\PWO_ePerceptor\Source\build\src\Native_ePerceptor_Dll\Native_ePerceptor_Lib.lib(PerceptorHost.obj) Native_ePerceptor_Dll 

当我看着库正在建设精细(Native_ePerceptor_Lib.lib)的buildlogs。这是失败的DLL。

最后但并非最不重要的是,项目必须使用CMake创建(以便能够解决不同的设置)。您可以在下面找到.cu,Lib .cpp和Dll .cpp的片段。我浏览了互联网以找到解决方案,但大多数解决方案都是关于一个项目中的问题,而不是关于图书馆。我现在非常绝望,所以我希望你们中的一些人能指出什么是问题,希望有什么可能的解决方案。 还有一件事,我很确定所有必要的图书馆都包含在内(cudart,cuda)。

Kernel.cu

#include <cuda\cuda_runtime.h> 

__global__ void add(int a, int b, int *c) 
{ 
    *c += a + b; 
    printf("%i + %i = %i \n", a, b, *c); 
} 

extern "C" void Add2And7(int *c) 
{ 
    int *dev_c; 

    //Allocate GPU memory 
    cudaMalloc((void**)&dev_c, sizeof(int)); 

    add <<<1, 1>>>(2, 7, dev_c); 

    //Copy GPU to CPU 
    cudaMemcpy(c, dev_c, sizeof(int), 
     cudaMemcpyDeviceToHost); 

    //printf("number is %u \n", &c); 

    //Free allocated GPU memory 
    cudaFree(dev_c); 
} 

PerceptorHost.cpp

//Forward declaration 
extern "C" void Add2And7(int *c); 

void PerceptorHost::UpdatePerceptorHost() 
{ 
    if (!g_bIsBooted) 
     return; 

    if (!m_bTestKernel) 
    { 
     int output = 0; 
     Add2And7(&output); 
     printf("2 + 7 = %i \n", output); 
     m_bTestKernel = true; 
    } 
} 

DLL.cpp

extern "C" NATIVEDLL_API void __cdecl UpdatePerceptorHost() 
{ 
    PERCEPTORHOST->UpdatePerceptorHost(); //Update the PerceptorHost and all it's managers 
} 

CMake的

######################################################################## 
# Add all source files to variables 
# CPU Source Files 
FILE(GLOB SRCS *.cpp) 
FILE(GLOB HDRS *.h) 
FILE(GLOB CUDA_HDRS 
     ${CMAKE_SOURCE_DIR}/include/cuda/*.h) 
FILE(GLOB CALIBRATION_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Calibration/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Calibration/*.h)  
FILE(GLOB CORE_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Core/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Core/*.h) 
FILE(GLOB DATAPROVIDER_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Data/DataProvider/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Data/DataProvider/*.h) 
FILE(GLOB RESOURCEMANAGER_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Data/ResourceManager/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Data/ResourceManager/*.h)  
FILE(GLOB DEBUG_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Debug/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Debug/*.h) 
FILE(GLOB EXCEPTION_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Exceptions/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Exceptions/*.h) 
FILE(GLOB HELPERS_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.h)   
FILE(GLOB VIDEOWRITER_FILES 
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
     ${CMAKE_CURRENT_SOURCE_DIR}/VideoWriter/*.cpp 
     ${CMAKE_CURRENT_SOURCE_DIR}/VideoWriter/*.h) 
# GPU Source Files  
FILE(GLOB GPU_HELPERS_FILES 
     ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cuh 
     ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cu)  

######################################################################## 
# Group all source files 
SOURCE_GROUP("Calibration" FILES ${CALIBRATION_FILES}) 
SOURCE_GROUP("Core" FILES ${CORE_FILES}) 
SOURCE_GROUP("DataProvider" FILES ${DATAPROVIDER_FILES}) 
SOURCE_GROUP("ResourceManager" FILES ${RESOURCEMANAGER_FILES}) 
SOURCE_GROUP("Debug" FILES ${DEBUG_FILES}) 
SOURCE_GROUP("Exceptions" FILES ${EXCEPTION_FILES}) 
SOURCE_GROUP("Helpers" FILES ${HELPERS_FILES}) 
SOURCE_GROUP("VideoWriter" FILES ${VIDEOWRITER_FILES}) 

######################################################################## 
# Set this part as static lib 
IF (D_ENABLE_LIBRARY_CUDA) 
CUDA_ADD_LIBRARY(Native_ePerceptor_Lib 
    ${CUDA_HDRS} 
    ${CALIBRATION_FILES} 
    ${CORE_FILES} 
    ${DATAPROVIDER_FILES} 
    ${RESOURCEMANAGER_FILES} 
    ${DEBUG_FILES} 
    ${EXCEPTION_FILES} 
    ${HELPERS_FILES} 
    ${VIDEOWRITER_FILES} 
    ${SRCS} 
    ${HDRS} 
    ${GPU_HELPERS_FILES} 
    ) 
ELSE() 
    ADD_LIBRARY(Native_ePerceptor_Lib 
    ${CUDA_HDRS} 
    ${CALIBRATION_FILES} 
    ${CORE_FILES} 
    ${DATAPROVIDER_FILES} 
    ${RESOURCEMANAGER_FILES} 
    ${DEBUG_FILES} 
    ${EXCEPTION_FILES} 
    ${HELPERS_FILES} 
    ${VIDEOWRITER_FILES} 
    ${SRCS} 
    ${HDRS} 
    ) 
ENDIF() 

######################################################################## 
# Add preprocessor defines 
IF (D_ENABLE_LIBRARY_CUDA) 
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11 FATAL_ERROR) 
    FIND_PACKAGE(CUDA REQUIRED) 
    INCLUDE_DIRECTORIES(
     ${CUDA_INCLUDE_DIRS} 
    ) 
    set(CUDA_ENABLED ON) 
    add_definitions(-DCUDA_ENABLED=1) 
ENDIF (D_ENABLE_LIBRARY_CUDA) 
IF (D_ENABLE_LIBRARY_OpenCV) 
    add_definitions(-DOPENCV_ENABLED=1) 
ENDIF (D_ENABLE_LIBRARY_OpenCV) 
IF (D_ENABLE_LIBRARY_Glut) 
    add_definitions(-DGLUT_ENABLED=1) 
ENDIF (D_ENABLE_LIBRARY_Glut) 

######################################################################## 
# Include Directories 
TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib 
    ${CUDA_LIBRARIES}) 

TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib 
    ${OpenCV_LIBRARIES}) 

TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib 
    ${Tobii_LIBRARIES}) 

TARGET_LINK_LIBRARIES(Native_ePerceptor_Lib 
    ${Glut_LIBRARIES}) 
+2

我只是想你的CMake文件的组成只是一个简化版本'Kernel.cu'和'在Linux上,GCC,CUDA 7和CMake的3.0 PerceptorHost.cpp'。 2,并成功编译并链接。请将您的代码转换为最小但可编译的示例(即尽可能剥离),以重现错误。提供您使用的工具版本的更多细节。考虑将CMake升级到最新版本。 –

+0

嗨,thx的提示。我试图将所有东西都转换成更小的设置(仍然使用相同的设置 - Lib - > Dll - > CMD进行测试)。 你可以在这里下载:http://we.tl/DITxuAm3Dd。 如果你可以看一看,那将会很棒。 我的工具是:Windows 8.1,CMakeGUI 3.2.2,NVCC,CUDA 7.0 – TheGoozah

+0

您的代码仍然太多,除此之外,我不能在Linux上构建它,因为您使用的是Windows特定包含等等。但是,为什么你有定义'void Add2And7(int * c)'作为'__device__'函数?你从主机调用它,所以它不能被装饰成'__device__'。 –

回答

1

奥凯,我是能够解决的问题,而先前提到的解决方案(改变构建定制+设置文件,CUDA C/C++)

的问题是确实的符号我定义我的CUDA函数的头文件没有被导出。因此,对于我的项目结构(LIB - > DLL - > CMD),这是一个问题。我能够在LIB - > CMD结构中使用它。我决定通过定义头功能如下问题:的

extern "C" __declspec(dllexport) void Add2And7(int *); 

代替:

extern "C" void Add2And7(int *); 

我不知道是否有什么不对这样(它的工作原理:))? 如果我查看MSDN,我认为它使用export关键字很好。

使用_declspec(dllexport)的

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL.