Win32 下动态链接库 (DLL) 机制笔记
来自Jack's Lab
(版本间的差异)
第41行: | 第41行: | ||
完了会生成 simple.dll simple.lib | 完了会生成 simple.dll simple.lib | ||
− | + | ||
+ | <br><br> | ||
+ | |||
=== 加载时动态链接测试 === | === 加载时动态链接测试 === | ||
第200行: | 第202行: | ||
<br><br><br><br> | <br><br><br><br> | ||
+ | <br><br> | ||
+ | <br><br> |
2013年9月24日 (二) 17:19的最后版本
目录 |
[编辑] 1 准备
使用 VC++ 带的命令行编译器 cl 前,需用 "C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat" 设置环境变量:
C:\> cd workspace\dll C:\workspace\dll> "C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"
[编辑] 2 DLL 导出简单 C 函数
simple.cc:
#include <stdio.h> #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif __declspec(dllexport) int myPuts(char *lpszMsg) { printf("%s\n", lpszMsg); return 1; } #ifdef __cplusplus } #endif
编译生成 DLL:
cl /LD /Fesimple.dll simple.cc
选项 /LD 告诉编译器创建 DLL
完了会生成 simple.dll simple.lib
[编辑] 2.1 加载时动态链接测试
#include <windows.h> int myPuts(char *str); // a function from a DLL int main(VOID) { int Ret = 1; Ret = myPuts("Using the DLL function, HaHaHaHa, Tutututu\n"); return Ret; }
以上保存为 load.time.link.c
编译之:
cl /Feload.time.link.exe load.time.link.c simple.lib
simple.lib 为 simple.dll 对应的 import library,链接时为链接器 link.exe 所需要
[编辑] 2.2 运行时动态加载测试
#include <stdio.h> #include <windows.h> typedef int (*MYFUNC)(char *); VOID main(VOID) { HINSTANCE hinstLib; MYFUNC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; //用 LoadLibrary() 加载 simple.dll hinstLib = LoadLibrary(TEXT("simple")); // If the handle is valid, try to get the function address. if (hinstLib != NULL) { //用 GetProcAddress() 获取 DLL 中函数地址 ProcAdd = (MYPROC) GetProcAddress(hinstLib, TEXT("myPuts")); // If the function address is valid, call the function. if (NULL != ProcAdd) { fRunTimeLinkSuccess = TRUE; (ProcAdd) (TEXT("Message via DLL function, HaHaHa, TUTUTUTUTU\n")); } // Free the DLL module. fFreeResult = FreeLibrary(hinstLib); } if (! fRunTimeLinkSuccess) printf("Load DLL failed\n"); }
存为 run.time.link.c,如下命令编译之:
cl /Ferun.time.link.exe run.time.link.c
[编辑] 3 DLL 中导出C++ 类
与导出 C 风格的函数类似,在定义类时用 __declspec(dllexport):
class __declspec(dllexport) MyCppClass { ...... };
编译时,依然用:
cl /Fesimple.dll /LD smiple.cc
加载时动态链接,则要在使用前加 __declspec(dllimport) 声明之:
class __declspec(dllimport) MyCppClass;
如下所示列:
---------- comcat.h: ---------- #ifndef _MY_CMATH_H_ #define _MY_CMATH_H_ #ifdef _CLASS_INDLL_ #define _CLASS_DECL_ __declspec(dllexport) #else #define _CLASS_DECL_ __declspec(dllimport) #endif class _CLASS_DECL_ CMath { public: int Add(int a,int b); CMath(); ~CMath(){}; }; #endif
comcat.cc:
#include "comcat.h" CMath::CMath() { }; int CMath::Add(int a, int b) { return a + b; }
如下命令生成 DLL:
cl /LD /Fecomcat.dll /D_CLASS_INDLL_ comcat.cc
[编辑] 3.1 加载时动态链接测试
class.load.test.cc
#include "comcat.h" #include <iostream> int main() { CMath *cm = new CMath; std::cout << "cmath's result:" << cm->Add(5, 8) << std::endl; return 0; }
如下命令编译之:
cl /Feclass.load.test.exe class.load.test.cc comcat.lib