Create a Windows DLL
The first step is to create a Windows DLL and export the functions that will be called by other methods.
Listing of Animal.h
1 2 3 4 5 6 7 8 9 10 11 | #include <string> using namespace std; class Animal { private: string name; public: Animal(string); virtual void print_name(); }; |
Listing of Animal.cpp
1 2 3 4 5 6 7 8 9 10 | #include <iostream> #include "Animal.h" using namespace std; Animal::Animal(string name):name (name){} void Animal::print_name(){ cout << "Name is " << this->name << endl; } |
The Animal.h and Animal.cpp files are placed in the include and src folders under the [example root folder]\animallib_shared\ folder, as shown below.
The next thing to do is to create the CMakeLists.txt in the Windows DLL project e.g. [example root folder]\animallib_shared\ folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | cmake_minimum_required(VERSION 2.8.6) project (animallib) set (CMAKE_BUILD_TYPE Debug) #include *.h files under include folder and #the project's output folder e.g. Debug include_directories (include ${PROJECT_BINARY_DIR}) #compile all *.cpp source files under src folder file (GLOB SOURCES "src/*.cpp") #output library as animallib.* #output library export file *.lib and #output macro definitions include file include (GenerateExportHeader) add_library(animallib SHARED ${SOURCES}) GENERATE_EXPORT_HEADER (animallib BASE_NAME animallib EXPORT_MACRO_NAME animallib_EXPORT EXPORT_FILE_NAME animallib_Export.h STATIC_DEFINE animallib_BUILT_AS_STATIC ) |
Next, we have to modify the header (*.h) and source code (*.cpp) files to add in the Windows export macro animallib_EXPORT and cmake generated header file animallib_Export.h.
Listing of modified animal.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <string> #include "animallib_Export.h" using namespace std; class Animal { private: string name; public: animallib_EXPORT Animal(string); virtual animallib_EXPORT void print_name(); }; |
1 2 3 4 5 6 7 8 9 10 11 12 | #include <iostream> #include "Animal.h" #include "animallib_Export.h" using namespace std; animallib_EXPORT Animal::Animal(string name):name (name){} animallib_EXPORT void Animal::print_name(){ cout << "Name is " << this->name << endl; } |
Open up a Windows Command prompt and change directory to the build folder of the Windows DLL project e.g. [example root folder]\animallib_shared\build\ folder.
Type in the cmake command (assuming cmake is in the PATH environment variable):
C:> cd \path\to\example\animallib_shared\build
C:> cmake ..
Build files are generated |
The generated build files |
Compilation messages |
The generated *.dll and export library *.lib files under [example root folder]\animallib_shared\build\Debug\ |
Now that the Windows DLL has been generated and the functions exported, the next thing is to use the DLL's classes and functions in an application e.g. UseAnimalLib project under [example root folder]\useanimallib\]
Listing of uselib.cpp
Then create a CMakeLists.txt file under the [example root folder]\useanimallib\ folder.
Open up a Windows Command Prompt. Change directory to the [example root folder]\useanimallib\build folder.
C:> cd \path\to\example\useanimallib\build
C:> cmake ..
Open up the generated solution file e.g. [example root folder]\useanimallib\build\Debug\uselib.sln using Visual Studio and build the solution.
Listing of uselib.cpp
1 2 3 4 5 6 7 8 9 10 11 12 | #include "Animal.h" #include "animallib_Export.h" int main(int argc, char *argv[]){ //Create a new animal instance with name Dog Animal animal("Dog"); //try to call the class's print_name method animal.print_name(); return (0); } |
Then create a CMakeLists.txt file under the [example root folder]\useanimallib\ folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | cmake_minimum_required(VERSION 2.8.6) project (UseAnimalLib) set (EXAMPLE_DIR d:/path/to/example/root/folder) set (PROJECT_LINK_LIBS animallib.dll) link_directories (${EXAMPLE_DIR}/animallib_shared/build/Debug) include_directories (${EXAMPLE_DIR}/animallib_shared/include ${EXAMPLE_DIR}/animallib_shared/build) #compile all *.cpp source files under src folder file (GLOB SOURCES "src/*.cpp") add_executable(uselib ${SOURCES}) target_link_libraries (uselib ${PROJECT_LINK_LIBS}) |
Open up a Windows Command Prompt. Change directory to the [example root folder]\useanimallib\build folder.
C:> cd \path\to\example\useanimallib\build
C:> cmake ..
The build files are generated |
The generated build files |
Building the solution |
The executable that uses the Windows DLL can now be run in a Command Prompt, assuming the DLL is in the PATH environment variable, as shown below.
Thanks for the clear, concise and complete tutorial. Hard to come accross high quality resources like this :)
ReplyDeleteGreat post! Only issue I had was that everything worked perfectly until the very end where uselib.exe won't print out "Name is Dog". I don't get any errors in the process, but the very last step seems off for me. Your instructions say to build \useanimallib\build\Debug\uselib.sln, but the only sln file I have after using cmake is still in the build directory (not Debug) and it's UseAnimalLib.sln. So I build that to end up with uselib.exe. Interestingly, adding a custom print message will work, just not that from the print_name method of the class packaged into the dll. Any idea what's going on?
ReplyDelete