Ich habe ein einfaches Projekt-Setup für ein OpenGL-Projekt für die Universität.
Ein API-Projekt, in dem jede Bibliothek, die ich verwenden möchte (GLEW, GLFW, GLM), statisch verlinkt ist. Diese Bibliotheken sollten mit meinem eigenen API-Code in einer einzigen DLL-Datei exportiert werden.
Das andere Projekt (das eigentliche) sollte nur eine Abhängigkeit haben, die DLL. Über diese DLL soll das Projekt Zugriff auf den API-Code und alle in der API verlinkten Bibliotheken zu erhalten.
Mein Problem ist, dass ich innerhalb der API Zugriff auf alle Funktionen aller von mir verknüpften Bibliotheken habe. Aber innerhalb des eigentlichen Projekts, das die API als Abhängigkeit hat, kann ich die Funktionen zwar aufrufen und der Compiler gibt keinen Fehler aus, da sich die Funktionsdeklaration in den verknüpften Header-Dateien befindet, der Linker findet die Funktionsdefinition jedoch nicht in der DLL, dh der Build der API exportiert die verknüpften Bibliotheken nicht in die DLL.
Ich habe im Projekt also nur Zugriff auf meinen selbstgeschrieben Code und nicht auf die LIBS innerhalb der API
Im API-Projekt habe ich auch die erforderlichen Präprozessordefinitionen definiert:
_GLFW_BUILD_DLL in der API und GLFW_DLL im Project:
C++-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| from "glfw3.h" l. 233-245
#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) #define GLFWAPI __declspec(dllexport) <----- das hier ist in der API aktiv #elif defined(_WIN32) && defined(GLFW_DLL) #define GLFWAPI __declspec(dllimport) <----- das hier ist im Projekt aktiv #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) #define GLFWAPI __attribute__((visibility("default"))) #else #define GLFWAPI #endif |
GLEW_BUILD in der API:
C++-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| from "glew.h" l. 200-208
#ifdef GLEW_STATIC #define GLEWAPI extern #else #ifdef GLEW_BUILD #define GLEWAPI extern __declspec(dllexport) <----- das hier ist in der API aktiv #else #define GLEWAPI extern __declspec(dllimport) <----- das hier ist im Projekt aktiv #endif #endif |
Außerdem habe ich die Linkeroption /WHOLEARCHIVE für die 3 LIBS verwendet:
Meine Linker-Optionen für Debug x86:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| /OUT:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.dll" /MANIFEST /NXCOMPAT /PDB:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.pdb" /DYNAMICBASE "glew32sd.lib" "glfw3.lib" "opengl32.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.lib" /DEBUG /DLL /MACHINE:X86 /INCREMENTAL /PGD:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin-int\Debug\Win32\CGAPI.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"D:\Programmierung\C++-Projekte\CG-Project\Dependencies\GLFW\Win32\lib-vc2019\" /LIBPATH:"D:\Programmierung\C++-Projekte\CG-Project\Dependencies\GLEW\lib\Release\Win32\" /TLBID:1 |
Die von mir hinzugefügten Linker-Optionen:
Quelltext
1: 2: 3:
| /WHOLEARCHIVE:glew32sd.lib (in Debug) /WHOLEARCHIVE:glew32s.lib (in Release) /WHOLEARCHIVE:glfw3.lib /WHOLEARCHIVE:opengl32.lib |
Nachdem ich diese Linker Option verwendet habe, bekam ich den Fehler, dass die glew.res Datei bereits spezifiziert ist. Daher musste ich den glew Quell-Code herunterladen und die statischen Bibliotheken selbst builden und zwar ohne eine .res Datei. Nachdem ich die neuen LIBS gebuildet und verlinkt hatte, bekam ich beim build der API keine Fehler mehr, allerdings sind die Funktionen der verlinkten LIBS vom Linker immer noch nicht zu finden, was heißt, das sie nachwievor nicht in die DLL exportiert werden.
Hier ein Link zum Downmload des Projekt-Setups mit den selbst gebuildeten GLEW LIBS, da der Anhang angeblich mit 5MB zu klein ist, obwohl die Datei nur 4,6MB groß ist:
workupload.com/file/dRXSCZEweLW
Solution-Rebuild-Output:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| 1>------ Rebuild All started: Project: CGAPI, Configuration: Debug Win32 ------ 1>CGWindow.cpp 1> Creating library D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.lib and object D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.exp 1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library 1>CGAPI.vcxproj -> D:\Programmierung\C++-Projekte\CG-Project\CGAPI\bin\Debug\Win32\CGAPI.dll 1>Done building project "CGAPI.vcxproj". 2>------ Rebuild All started: Project: CG-Project, Configuration: Debug Win32 ------ 2>main.cpp 2>main.obj : error LNK2019: unresolved external symbol __imp__glGetString@4 referenced in function _main 2>main.obj : error LNK2019: unresolved external symbol __imp__glewInit@0 referenced in function _main 2>main.obj : error LNK2019: unresolved external symbol __imp__glfwMakeContextCurrent referenced in function _main 2>D:\Programmierung\C++-Projekte\CG-Project\CG-Project\bin\Debug\Win32\CG-Project.exe : fatal error LNK1120: 3 unresolved externals 2>Done building project "CG-Project.vcxproj" -- FAILED. ========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ========== |
Hoffe auf Hilfe
LG Kasko