静态库 :链接时候被链接到可执行文件,文件体积较大
使用静态库需要有头文件和 *.lib文件
动态库:不被链接进入,动态加载,生成文件体积小
使用动态库需要有头文件 lib dll或者dll文件
库的用途:调用不同的库实现不同的功能,实现代码复用
静态库编写
加上extern "C"代表用C语言实现的函数
通常C语言写出来的库都比较通用
头文件xxx.h
1 2 3 4
| #ifndef LIB_H #define LIB_H /*extern "C" */int add(int x,int y); #endif
|
源文件xxx.c
1 2 3 4 5 6
| #include "staticlib.h"
int add(int x,int y) { return x + y; }
|
动态库编写
加上__stdcall后库中函数的名字会改变
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef _DLL_H_ #define _DLL_H_
#ifdef _EXPORT #define DECLSPEC __declspec(dllexport) // 导出 #else #define DECLSPEC __declspec(dllimport) // 导入 #endif
DECLSPEC int add(int x,int y); DECLSPEC int __stdcall add2(int x,int y); #endif // _DLL_H_
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include "dll.h" #include <stdio.h> #include <Windows.h> int add(int x,int y) { return x + y; } int __stdcall add2(int x,int y) { return x + y; }
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: printf("process attach of dll\r\n"); break; case DLL_THREAD_ATTACH: printf("thread attach of dll\r\n"); break; case DLL_THREAD_DETACH: printf("thread detach of dll\r\n"); break; case DLL_PROCESS_DETACH: printf("process detach of dll\r\n"); break; }
return TRUE; }
|
调用静态库和动态库
调用静态库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <stdio.h> #include <windows.h> #include "..\staticlib\staticlib.h"
#pragma comment(lib, "..\\Debug\\staticlib.lib" )
int main() { // 静态库调用 int c = add(1,2); printf("%d\r\n", c);
system("pause"); return 0; }
|
1 2
| //告诉编译器将staticlib.lib链接到本程序中 #pragma comment(lib, "..\\Debug\\staticlib.lib" )
|
或者可以在VS中添加

调用动态库
第一种方法隐式调用需要有头文件,lib文件,dll文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <stdio.h> #include <windows.h> #include "..\dll\dll.h" #pragma comment(lib, "..\\Debug\\dll.lib" )
typedef int (*lpAddFun)(int, int); int main() {
// 隐式调用 int c = add(1,2); printf("%d\r\n", c);
system("pause"); return 0; }
|
第二种方法只需要有dll文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <stdio.h> #include <windows.h> #include "..\dll\dll.h" #pragma comment(lib, "..\\Debug\\dll.lib" )
typedef int (__stdcall *lpAddFun)(int, int); typedef int (*lpAddFun2)(int, int);
int main() {
// 显示调用DLL HINSTANCE hDll; //DLL句柄 lpAddFun addFun; //函数指针 hDll = LoadLibrary("..\\Debug\\dll.dll"); if (hDll != NULL) { addFun = (lpAddFun)GetProcAddress(hDll, "_add@8"); //addFun = (lpAddFun)GetProcAddress(hDll, MAKEINTRESOURCE(1)); if (addFun != NULL) { int result = addFun(1, 2); printf("%d\r\n", result); } FreeLibrary(hDll); }
system("pause"); return 0; }
|
如果在函数调用约定使用的是__stdcall ,函数名字就会发生改变
def文件可以告诉编译器那个函数要作为输出函数
1 2 3
| LIBRARY dll文件名 EXPORTS // 代表导出 函数名 @ 序号
|
例如
1 2 3 4 5
| LIBRARY my.dll EXPORTS add @ 1 push @ 3 sub @ 2
|