Erreur de lien CUDA (Lib to Dll)

J’essaie de créer un framework pour pouvoir utiliser le code CUDA dans plusieurs moteurs de jeux. Pour pouvoir communiquer avec tous les moteurs utiles, le cadre se compose de deux parties principales. Un lib et une DLL. La bibliothèque contient toutes les fonctionnalités (CUDA et C ++ standard) et la DLL sert de pont pour appeler des fonctions à partir de la bibliothèque.

Maintenant, tout était en cours d’exécution jusqu’à ce que j’ai inclus un fichier .cu. Lorsque je construis, j’obtiens l’erreur suivante:

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 

Quand je regarde les buildlogs, la Lib est en train de construire (Native_ePerceptor_Lib.lib). C’est la DLL qui échoue.

Enfin, le projet doit être créé à l’aide de CMake (pour pouvoir traiter différentes configurations). Ci-dessous, vous trouverez des extraits de .cu, Lib .cpp et Dll .cpp. J’ai parcouru les sites Web pour trouver une solution, mais la plupart des solutions concernent les problèmes d’un projet et non les bibliothèques. Je suis assez désespéré pour le moment, alors j’espère que certains d’entre vous pourront expliquer le problème et, espérons-le, quelle solution possible. Une dernière chose, je suis à peu près sûr que toutes les bibliothèques nécessaires sont incluses (cudart, cuda).

Kernel.cu

 #include  __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 <<>>(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}) 

Oke, j’ai pu résoudre le problème sans la solution mentionnée précédemment (modification du fichier de configuration Build Customization + en CUDA C / C ++)

Le problème était qu’en effet, les symboles de mon fichier d’entête qui définissaient ma fonction CUDA n’étaient pas exportés. Donc, avec ma structure de projet (LIB -> DLL -> CMD), c’était un problème. J’ai pu l’utiliser dans une structure LIB -> CMD. J’ai résolu le problème en définissant la fonction d’en-tête comme suit:

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

au lieu de:

 extern "C" void Add2And7(int *); 

Je ne sais pas s’il y a quelque chose qui ne va pas avec ça (ça marche :))? Si je vérifie MSDN, je pense que cela va bien en utilisant le mot clé export.

Utilisation de _declspec (dllexport)

Les atsortingbuts dllexport et dllimport storage-class sont des extensions spécifiques aux langages C et C ++ propres à Microsoft. Vous pouvez les utiliser pour exporter et importer des fonctions, des données et des objects depuis ou vers une DLL.