CUDA链接错误(Lib到Dll)

时间:2015-05-19 08:24:51

标签: c++ c dll cuda

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

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

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

当我查看构建日志时,Lib构建正常(Native_ePerceptor_Lib.lib)。这是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})

1 个答案:

答案 0 :(得分:1)

Oke,我能够在没有前面提到的解决方案的情况下解决问题(将Build Customization +设置文件更改为CUDA C / C ++)

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

next()

而不是:

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

我不知道这样做是否有任何问题(有效:))? 如果我查看MSDN,我认为使用export关键字很好。

使用_declspec(dllexport)

  

dllexport和dllimport存储类属性是   特定于Microsoft的C和C ++语言扩展。您可以使用   它们用于导出和导入函数,数据和对象   DLL。