This article uses dev-c++, and if it involves operations that are not the same in VC++, they will be differentiated appropriately.
Project 1: Creating a DLL
1, create a DLL type of project, currently named dlltest, and choose the appropriate path to save.
2. In the generated pre-set code, add the following code
//Here's the header file. #ifndef _DLL_H_ #define _DLL_H_ #if BUILDING_DLL #define DLLIMPORT __declspec(dllexport) #else #define DLLIMPORT __declspec(dllimport) #endif class DLLIMPORT DllClass { public: DllClass(); virtual ~DllClass(); void HelloWorld(char* info); }; extern "C" { DLLIMPORT int HW(int n); } DLLIMPORT int func(int n); #endif
/*This is the main document.*/ #include "" #include <> DllClass::DllClass() { } DllClass::~DllClass() { } void DllClass::HelloWorld(char* info) { MessageBox(0, info,"Hi",MB_ICONINFORMATION); } DLLIMPORT int HW(int n) { return n; } DLLIMPORT int func(int n) { return n; } BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: { break; } case DLL_THREAD_ATTACH: { break; } case DLL_THREAD_DETACH: { break; } } /* Return TRUE on success, FALSE on failure */ return TRUE; }
In the code above, we have added two export functions, HW and func, and a DllClass (auto-generated) export class.
After clicking compile, we can see in the project folder, this is the target dynamic link library we need. Then it is the lib file that is needed in vc.
3. extern "C" description
Currently you can hit the file with Notepad and see the following:
The address offset of the HW function with extern "C" is still HW, while the address offset of the func function without extern "C" becomes _Z4funci, which will be used in the process of dynamically calling the exported function.
Project 2: Dynamically calling dll-exported functions
1. Create another C++ project and put the dll file generated by project one into the project folder:
2. Use LoadLibrary and and GetProcAddress to dynamically load the dynamic link library and call the exported function:
#include <iostream> #include <> using namespace std; int main() { HMODULE hMod=LoadLibrary(""); if(hMod==NULL) { cerr<<"load lib error"; return 1; } Func f=(Func)GetProcAddress(hMod,"HW"); cout<<f(200); FreeLibrary(hMod); return 0; }
In GetProcAddress, calling the HW function allows you to pass the offset HW directly;
If the func function is called, pass in the offset "_Z4funci"; because the func function is not declared as extern "C".
3, special note, the current way can not use LoadLibrary and GetProcAddress to get out of the export class.
This is because GetProcAddress gets the address offset of the function and has nothing to do with the class. In order to be able to use the exported class dynamically, it is necessary to use functions that make a purely virtual function the base class that will export the functions that create and destroy the class. This is done as follows:
// #include <> #include <> class virtualXXX { public: virtual void functionOne() = 0; virtual void functionTwo() = 0; }; #if defined(_WINDOWS) #ifdef XXX_API #define XXX_API __declspec(dllexport) #else #define XXX_API __declspec(dllimport) #endif #else #define XXX_API #endif class XXX_API xxx : public virtualXXX { public: void functionOne() { printf ( "One\n" ); } void functionTwo() { printf ( "Two\n" ); } }; extern "C" XXX_API virtualXXX * create(); extern "C" XXX_API void delete_object( virtualXXX * p ); // virtualXXX * create() { return ( new xxx() ); } void delete_object( virtualXXX * p ) { if ( p ) { delete p; p = NULL; } }
Dynamic invocation:
#include <> typedef virtualXXX *(fun_create)(void); fun_create* vc_create = NULL; int main() { HINSTANCE dllHandle = NULL; dllHandle = LoadLibrary( "Win32_Test_dll.dll" ); vc_create = ( fun_create* )GetProcAddress( dllHandle,"create" ); virtualXXX * xxxHandle = vc_create(); xxxHandle->functionOne(); xxxHandle->functionTwo(); delete_object(xxxHandle); }
This method references the articleC++ dynamic library export class, and the use of the, which the blogger did not actually test.
Project 3: Static calls to exported classes
To statically call a dll, in VC++ you need the header file, the dll, and the corresponding lib file (i.e., the one generated in project one). Then use #pragma comment(lib, "lib file path") to configure the lib path to the compiler, and then call it afterwards. For details, please refer to"Generating DLLs and Calling Them in c++".。
This article focuses on static calls under Dev-C++. For MinGW64 static call dll, only dll file and related header files are needed, the project structure is as follows:
The code for calling the class in it is as follows:
#include <iostream> #include <> #include "" using namespace std; int main() { DllClass c; char str[]="hello"; (str); return 0; }
As you can see, there is no need to set anything in the code. Because only during the linking process c++ goes for the real address of the class DllClass.
When compiling to an exe, there are two methods as follows:
Method 1, you can use the command line to compile: through cmd into the path of the folder where it is located, run:g++ -o -I . -L . -ldlltest
The compilation parameters are described below:
-I search the directory for header files
-I . Search for header files in the current folder
-L searches the directory for dynamic libraries
-L . Search for dynamic libraries in the current folder
Method 2. Add the parameter to the compilation options:
If you find it too cumbersome to compile from the command line, you can add -I -L and -l to Dev-C++'s compiler options.
By clicking "Compile and Run", the corresponding dll will be found and compiled to generate the exe file correctly.
This article on Dev-C++ to create and call the dynamic link library dll to the end here, welcome to correct:)