隐式链接
I:DLL创建
a:创建一个Smart Device的Win32项目
b:选择WM6的SDK
c:选择Dll并导出
d:visual studio 自动生成的代码,这里加上了HelloWorld函数。
MyDll.cpp:
#include "stdafx.h" #include "MyDll.h" #include <windows.h> #include <commctrl.h>
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
// This is an example of an exported variable MYDLL_API int nMyDll=0;
// This is an example of an exported function. MYDLL_API int fnMyDll(void) { return 42; }
// This is the constructor of a class that has been exported. // see MyDll.h for the class definition CMyDll::CMyDll() { return; }
MYDLL_API void HelloWorld(void) { MessageBox (NULL, TEXT ("Hello World"), TEXT ("HelloWorld"), MB_OK); } |
MyDll.h:
// The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the MYDLL_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // MYDLL_API functions as being imported from a DLL, whereas this DLL sees symbols // defined with this macro as being exported. #ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif
// This class is exported from the MyDll.dll class MYDLL_API CMyDll { public: CMyDll(void); // TODO: add your methods here. };
extern MYDLL_API int nMyDll;
MYDLL_API int fnMyDll(void);
MYDLL_API void HelloWorld(void); |
头文件 MyDll.h还将用于调用MyDll.dll的文件,MYDLL_API __declspec(dllexport)用于MyDll.cpp,其中MYDLL_EXPORTS 定义在:
这样当调用该Dll的文件没有定义MYDLL_EXPORTS,则使用#define MYDLL_API __declspec(dllimport).
e:编译后将生成MyDll.dll和MyDll.lib,其中MyDll.lib用于调用该Dll的文件编译时使用,可以用dumpbin -exports查看该Dll导出的函数:
II:DLL调用
a:创建一个控制台程序DllTest,并将上面生成的Mydll.lib和MyDll.h拷贝到该项目的目录下
b:在link的input中加入MyDll.lib:
c:将MyDll.dll拷贝包SDk模拟器的Program Files/DllTest目录下,否则运行时找不到MyDll.dll会报错无法运行
d:运行Debug,就可以看到效果了:
动态加载
1:新建一个Smart Device的Win32项目
2:创建一个Dll,不要导出符号
3:MyDll_Def.cpp:
// MyDll_Def.cpp : Defines the entry point for the DLL application. //
#include "stdafx.h" #include <windows.h> #include <commctrl.h>
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }
void HelloWorld(void) { MessageBox (NULL, TEXT ("Hello World"), TEXT ("Hello World"), MB_OK); }
|
4:新建一个def文件,用于导出HelloWorld
LIBRARY "MyDll_Def"
EXPORTS HelloWorld |
5:创建一个DllTest_Def测试程序:
// DllTest_Def.cpp : Defines the entry point for the console application. //
#include "stdafx.h" #include <windows.h> #include <commctrl.h>
int _tmain(int argc, _TCHAR* argv[]) { HINSTANCE hInst;
hInst=LoadLibrary(TEXT("MyDll_Def.dll")); if(NULL == hInst) { MessageBox (NULL, TEXT ("Hello World"), TEXT ("Load MyDll_Def.dll error"), MB_OK); return -1; }
typedef void (*HELLOWORLDPROC)(); HELLOWORLDPROC HelloWorld=(HELLOWORLDPROC)GetProcAddress(hInst,TEXT("HelloWorld")); if(NULL == HelloWorld) { MessageBox (NULL, TEXT ("Hello World"), TEXT ("GetProcAddress HelloWorld error"), MB_OK); return -1; }
HelloWorld();
FreeLibrary(hInst);
return 0; } |
LoadLibrary用于动态加载Dll,GetProcAddress用于获取函数指针.
6:将MyDll.dll拷贝包SDk模拟器的Program Files/DllTest目录下,否则运行时找不到MyDll.dll会报错无法运行
7:运行Debug,就可以看到效果了: