I was having issued using FreeLibrary to unload a DLL (see this question for details). Basically the process was returning an exit code of 3 after calling FreeLibrary.
I looked at some other DLL projects that worked for me and realised that all the other DLLs were compiled with -static
, which I tried, and it worked! I'm wondering why this flag might help the program to free the library from memory. Reading this question, specifically Ahmed Masud's answer (quoted below) it seems to me that all it does is forces the application (or DLL, in this case) not to be dependent on runtime linking of other libraries - is this right?
The -static option links a program statically, in other words it does not require a dependency on dynamic libraries at runtime in order to run.
If so I'm not really sure why my DLL has to be linked with -static
to work, as it doesn't depend on any runtime linking anyway. To make sure of this, I've created a test DLL with empty header and source files, and built (with CMake 3.3 and MinGW w64 4.0) both versions:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Sure enough, compiling with the former allows my program to load and free the library successfully, but the latter causes an unkown error when I try to free the DLL. Thanks in advance for any insight into the matter.
Test Application Code
int main() {
HINSTANCE hDLL = LoadLibrary("../lib/libComms.dll");
if (hDLL) {
cout << "DLL loaded"<< endl;
}
cout << "Attempting to free" << endl;
//If I write a DllMain and place a breakpoint
//in there, debugger shows error to occur on this line:
auto res = FreeLibrary(hDLL);
if (!res) {
cout << "FreeLibrary failed with: " << GetLastError() << endl;
}
return 0;
} //Otherwise the issue only shows up after 'main' has returned
DLL Code
DLL.h
#ifndef PROJECT_DLL_H_H
#define PROJECT_DLL_H_H
#endif //PROJECT_DLL_H_H
And DLL.cpp is empty
*The DLL source files are just the default generated by CLion.
CMake File for DLL
project(SPOCK_Comms)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "F:\\SPOCK\\Roaming Server\\lib")
set(SOURCE_FILES DLL.h DLL.cpp)
add_library(Comms SHARED ${SOURCE_FILES})