写点什么

C++ 创建与调用 dll 动态链接库(MinGW64 Dev-C++)

  • 2024-09-09
    福建
  • 本文字数:2572 字

    阅读完需:约 8 分钟

本文使用的是 dev-c++,如果涉及到 VC++中不一样的操作,也会适当进行区分。


项目一:创建 DLL


1、创建一个 DLL 类型的项目,当前命名为 dlltest,并选择合适的路径进行保存。



 2、在生成的预设置代码中,加入如下代码


//这是头文件dll.h#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
复制代码


/*这是主体文件dllmain.cpp */#include "dll.h"#include <windows.h>
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;}
复制代码


在上面的代码中,我们加入了 HW 和 func 两个导出函数,以及一个 DllClass(自动生成)导出类。


点击编译后,我们可以在项目文件夹中,看到 dlltest.dll,这就是我们需要的目标动态链接库。libdlltest.a 则是 vc 里需要用到的 lib 文件。



3、extern "C"说明


当前可以用记事本打到 libdlltest.def 文件,可以看到如下内容:



加了 extern "C"的 HW 函数地址偏移量还是 HW,没有加 extern "C"的 func 函数,地址偏移量变成了_Z4funci。这个地址在动态调用导出函数的过程中会用到。


项目二:动态调用 dll 导出的函数


1、再创建一个 C++项目,将项目一生成的 dll 文件放入项目文件夹中:



 2、使用 LoadLibrary 和和 GetProcAddress 动态载入动态链接库,并调用导出的函数:


#include <iostream>#include <windows.h>using namespace std;
int main(){ HMODULE hMod=LoadLibrary("dlltest.dll"); if(hMod==NULL) { cerr<<"load lib error"; return 1; } Func f=(Func)GetProcAddress(hMod,"HW"); cout<<f(200); FreeLibrary(hMod); return 0;}
复制代码


在 GetProcAddress 中,调用 HW 函数可以直接传入偏移量 HW;


如果调用 func 函数,则要传入偏移量“_Z4funci”;因为 func 函数没有声明为 extern "C"。


3、特别备注,当前这种方式无法使用 LoadLibrary 和 GetProcAddress 获取导出类。


因为 GetProcAddress 获取的是函数的地址偏移量,为了可以动态使用导出的类,必须使用将一个纯虚函数做为基类,将导出创建和销毁类的函数。具体做法如下:


//dll.h#include <stdlib.h>#include <stdio.h>
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 );
//dll.cppvirtualXXX * create(){ return ( new xxx() );}
void delete_object( virtualXXX * p ){ if ( p ) { delete p; p = NULL; }}
复制代码


动态调用:


#include <Windows.h>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);}
复制代码


这个方法参考文章C++动态库导出类,及使用,博主未实际进行测试。


项目三:静态调用导出的类


静态调用 dll,在 VC++需要头文件、dll 和对应的 lib 文件(即项目一中生成的 libdlltest.a)。然后再使用 #pragma comment(lib,"lib 文件路径")对编译器进行配置 lib 路径,之后再进行调用。详细过程可以参考《c++生成DLL并调用》


本文着重调论 Dev-C++下的静态调用。对于 MinGW64 静态调用 dll,只需要 dll 文件和相关的头文件,项目结构如下:



其中 main.cpp 中调用类的代码如下:


#include <iostream>#include <windows.h>#include "dll.h" using namespace std;
int main(){ DllClass c; char str[]="hello"; c.HelloWorld(str); return 0;}
复制代码


可以看到,无需在代码中进行任何设置。因为只有在链接的过程 c++才会去找 DllClass 这个类的真实地址。

在编译成 exe 时,有如下两种方法:


方法一、可以使用命令行进行编译:


通过 cmd 进入 main.cpp 所在文件夹路径,运行:g++ -o main.exe main.cpp -I . -L . -ldlltest

即可编译生成可执行文件 exe。编译参数说明如下:


-I 搜索头文件的目录-I .在当前文件夹下搜索头文件-L 搜索动态库的目录-L .在当前文件夹下搜索动态库


方法二、将参数加入编译选项中:


如果觉得用命令行编译太麻烦,可以将-I -L 和-l 加入 Dev-C++的编译器选项中。



这样点击“编译运行”就可以正确找到对应的 dll 进行编译链接,正确生成 exe 文件。

 

本文关于 Dev-C++创建并调用动态链接库 dll 到这里就结束了,欢迎大家指正:)


文章转载自:咚..咚

原文链接:https://www.cnblogs.com/ddcoder/p/18400396

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
C++创建与调用dll动态链接库(MinGW64 Dev-C++)_快乐非自愿限量之名_InfoQ写作社区