C++里常使用链接库有两种方式:一种为静态的,使用lib库;另外一种是使用动态链接库,分为两种情况:1>将.h文件和lib文件加载到程序中,把dll文件和程序放在同一目录;2>程序中调用LoadLibrary和FreeLibrary动态加载和释放dll文件。
下面看两个对应的小例子:
1.使用静态链接库
首先建立一个空工程,修改工程生成的是lib库。代码:
- //----DllMain.h----
- //提供函数接口
- #pragma once
- extern "C" int __stdcall add(int a,int b); //使用extern "C"修饰导出接口为C函数
- //----DllMain.cpp----
- #include "DllMain.h"
- int __stdcall add(int a,int b)
- {
- return (a + b);
- }
这样编译就能生成lib文件了。使用Depends查看函数接口:有一个函数名为_add@8
然后可以创建一个项目使用此lib库,首先应该在工程属性里把lib文件设定为编译依赖库:
- #include <iostream>
- #include "../StaticDllTest/DllMain.h" //将必要的函数接口说明头文件包含进来
- using namespace std;
- int main()
- {
- cout << "Static lib is working ...add(1,2) = " ;
- cout << add(1,2) << endl; //调用lib库里的add函数
- return 0;
- }
到此静态链接库就可以使用了,需要:lib文件和.h函数接口说明文件
2.使用动态链接库
创建一个空工程,设定工程属性生成dll文件。代码:
- //DllMain.h
- //头文件用于说明函数接口
- #pragma once
- //#include <Windows.h>
- extern "C" __declspec(dllexport) int __stdcall add(int a, int b);
- //注意生成dll导出函数接口需要dllexport关键字
- //DllMain.cpp
- #include "DllMain.h"
- int __stdcall add(int a, int b)
- {
- return (a + b);
- }
这样编译成功后就生成了一个dll和一个lib文件。
1>使用lib .h dll 运行时动态,把头文件和lib文件包含进来;
- #include <iostream>
- #include "../DynamicDll/DllMain.h"
- #pragma comment(lib,"../bin/DynamicDll.lib") //加入lib库
- using namespace std;
- int main()
- {
- cout << add(1,2) << endl;
- return 0;
- }
程序执行需要dll文件,所以要把dll文件和执行程序放在同一目录下。
2>只使用dll文件:
- #include <iostream>
- #include <windows.h>
- using namespace std;
- typedef int (__stdcall *PFUN)(int,int);
- int main()
- {
- PFUN pAdd = NULL;
- HMODULE hDll = LoadLibrary("DynamicDll.dll");
- if (hDll)
- pAdd = (PFUN)GetProcAddress(hDll,_add@8);
- cout << pAdd(3,10) << endl;
- if (hDll)
- FreeLibrary(hDll);
- return 0;
- }
需要说明的是加载dll函数LoadLibrary须知道dll文件名才能调用,然后GetProcAddress也是根据导出dll文件里的函数名来取得函数的地址的。还有函数名_add@8是未经过导出模块定义时生成的dll文件里函数名就是这样了,如果使用DEF文件定义后导出的C风格函数就会像这样“add”没有那些标记符号。DEF文件内容格式如下:
- LIBRARY "DynamicDll"
- EXPORTS
- add @1
好了,到此常规的链接库学习就完成了,另外还有两类链接库和MFC有关,暂时不多研究。