DLL总结
来源:互联网 发布:asp企业网站源码下载 编辑:程序博客网 时间:2024/05/26 23:00
转载:点击打开链接
一、在dll中定义输出函数
总体有两种方法,一种是添加def定义文件,在def文件中定义要输出的函数;另一种是在源代码中待输出的函数前加上__declspec(dllexport)关键字。
1、添加def定义文件
dll_def.cpp文件:
<span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">#include <objbase.h>#include <iostream>void FuncInDll(){std::cout<<"FuncInDll is called!"<<std::endl;}BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void *lpReserved){HANDLE g_hModule;switch(dwReason){case DLL_PROCESS_ATTACH:hModule;break;case DLL_PROCESS_DETACH:g_hModule = NULL;break;default:break;}return TRUE;}</span></span></span>
dll_def.def文件
<span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">LIBRARYdll_def.dllDESCRIPTION'write by ycg'EXPORTSFuncInDll @1 PRIVATE</span></span></span>
用如下命令编译
cl /c dll_def.cpp
link /dll dll_def.obj /def:dll_def.def
再用dunpbin -exports dll_def.dll查看库的信息,可以发现该dll导出了函数FuncInDll。
2、__declspec(dllexport)
为每个dll写def显得繁杂,更多的是使用__declspec(dllexport)
Dll写法同上,去掉def文件,并在每个要输出的函数前面加上声明__declspec(dllexport)
<span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">__declspec(dllexport) void FuncInDll()</span></span></span>
然后编译链接
cl /c dll_withlib.cpp
link /dll dll_withlib.obj
这里要注意,C++编译器基于函数重载的考虑,会更改函数名,可以使用extern "C"指令来命令C++编译器以C编译器的方式来命名该函数。
<span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">extern "C" _declspec(dllexport) void FuncInDll()</span></span></span>
二、dll的调用方式
dll可通过隐式调用和显示调用来加载
1、显示调用
先调用LoadLibrary将dll库加载进程序
通过GetProcAddress函数获取库中函数的地址
通过函数指针调用
<span style="font-family:KaiTi_GB2312;font-size:14px;"><span style="font-family:KaiTi_GB2312;font-size:14px;">#include <windows.h>#include <iostream>int main(){//定义一个函数指针typedef void(* DLLWITHLIB)(void);//定义一个函数指针变量DLLWITHLIB pfFuncInDll = NULL;//加载DLLHINSTANCE hinst = ::LoadLibrary("dll_def.dll");if(NULL != hinst){std::cout<<"dll loaded"<<std::endl;}//找到dll里函数的地址pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll");//调用if(NULL != pfFuncInDll){(*pfFuncInDll)();}getchar();return 0;}</span></span>
2、隐式调用
dll包含两个文件,cpp文件和头文件
dll_object.h文件
<span style="font-family:KaiTi_GB2312;font-size:14px;">#ifdef DLL_OBJECT_EXPORTS#define DLL_OBJECT_API __declspec(dllexport)#else#define DLL_OBJECT_API __declspec(dllimport)#endif//导出函数DLL_OBJECT_API void FuncInDll(void);//导出全局变量extern DLL_OBJECT_API int g_nDll;//导出类class DLL_OBJECT_API CDll_Object{public:CDll_Object(void);void show(void);};</span>
dll_object.cpp文件
<span style="font-family:KaiTi_GB2312;font-size:14px;">#define DLL_OBJECT_EXPORTS#include <objbase.h>#include <iostream>#include "dll_object.h"DLL_OBJECT_API void FuncInDll(void){std::cout<<"FuncInDll is called!"<<std::endl;}DLL_OBJECT_API int g_nDll = 9;CDll_Object::CDll_Object(){std::cout<<"init of CDll_Object"<<std::endl;}void CDll_Object::show(){std::cout<<"function show in class CDll_Object"<<std::endl;}BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){HINSTANCE g_hModule;switch(dwReason){case DLL_PROCESS_ATTACH:g_hModule = (HINSTANCE)hModule;break;case DLL_PROCESS_DETACH:g_hModule = NULL;break;default:break;}return TRUE;}</span>
调用时,客户端引入头文件,并在链接时指明dll对应的lib文件位置和名称,然后如同调用api函数库中的函数一样调用dll中的函数
client.cpp
<span style="font-family:KaiTi_GB2312;font-size:14px;">#include "dll_object.h"#include <iostream>using namespace std;#pragma comment(lib, "dll_object.lib")int main(){cout<<"call dll"<<endl;cout<<"call function in dll"<<endl;//调用dll中的函数FuncInDll();//dll中的全局变量cout<<"global var in dll g_nDll = "<<g_nDll<<endl;//调用dll中的类CDll_Object obj;obj.show();return 0;}</span>
三、在一个dll中调用另一个dll
dll1.h
<span style="font-family:KaiTi_GB2312;font-size:14px;">#ifdef DLL_DLL1_EXPORTS#define DLL_DLL1_API __declspec(dllexport)#else#define DLL_DLL1_API __declspec(dllimport)#endifDLL_DLL1_API void FuncInDll1(void);DLL_DLL1_API void FuncInDll1(int);</span>dll1.cpp
<span style="font-family:KaiTi_GB2312;font-size:14px;">#define DLL_DLL1_EXPORTS#include <objbase.h>#include <iostream>#include "dll1.h"DLL_DLL1_API void FuncInDll1(void){std::cout<<"FuncInDll1 is called!"<<std::endl;}DLL_DLL1_API void FuncInDll1(int a){std::cout<<"FuncInDll1 is called! input param = "<<a<<std::endl;}BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){HINSTANCE g_hModule;switch(dwReason){case DLL_PROCESS_ATTACH:g_hModule = (HINSTANCE)hModule;break;case DLL_PROCESS_DETACH:g_hModule = NULL;break;default:break;}return TRUE;}</span>
dll2.h
<span style="font-family:KaiTi_GB2312;font-size:14px;">#include "dll1.h"#ifdef DLL_DLL2_EXPORTS#define DLL_DLL2_API __declspec(dllexport)#else#define DLL_DLL2_API __declspec(dllimport)#endifDLL_DLL2_API void FuncInDll2(void);DLL_DLL2_API void FuncInDll2(int);</span>
dll2.cpp
<span style="font-family:KaiTi_GB2312;font-size:14px;">#define DLL_DLL2_EXPORTS#include <objbase.h>#include <iostream>#include "dll2.h"#pragma comment(lib, "dll1.lib")//在DLL2中调用DLL1中的函数DLL_DLL2_API void FuncInDll2(void){FuncInDll1();std::cout<<"FuncInDll2 is called!"<<std::endl;}DLL_DLL2_API void FuncInDll2(int a){FuncInDll1(10);std::cout<<"FuncInDll2 is called! input param = "<<a<<std::endl;}BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){HINSTANCE g_hModule;switch(dwReason){case DLL_PROCESS_ATTACH:g_hModule = (HINSTANCE)hModule;break;case DLL_PROCESS_DETACH:g_hModule = NULL;break;default:break;}return TRUE;}</span>
0 0
- DLL总结
- DLL相关知识总结
- delphi封装DLL总结
- DLL声明的总结
- Dll知识小总结
- Symbian DLL 学习总结
- DLL编程总结
- dll编写总结
- dll与lib总结
- DLL编程总结
- C++调用DLL总结
- Dll 导出 别人总结
- ntdll.dll学习总结
- dll库总结1
- DLL注入学习总结
- win32 DLL 学习总结
- java中调用dll总结
- java 调用dll文件总结
- Eclipse 安装反编译插件jadclipse
- 堆排序
- Linux环境变量
- SQL Server 2000中全文检索的使用
- 图像分割方法介绍
- DLL总结
- PHP自学笔记详细版本(一)
- jquery的ajax的使用!
- LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- android setTag (int key, Object tag)抛出IllegalArgumentException的问题
- Android中关于Activity/ActionBarActivity/AppCompatActivity的区分与理解
- plot ErrorBar
- int main(int argc,char** argv)
- 该项不适于在指定状态下使用