现在只要做关于dll,为了dll有更好的应用以及跨平台,一般采用自己写,不用系统的生成!不管用dll做什么事情,如一般用在大型项目软件中或为3D引擎的dll,都采用自己编,我把这段代码放出后可能很多人觉得这个太简单了,但是越是简单的东西越不简单,我记得我以前和别人就讲hello,world的c程序,我讲了五个小时还没讲完。并且这也是所有的dll的基石。弄明白它是何等的重要。
.h 文件
#ifdef JUNO_EXPORTS
首先解释下XXX_ EXPORTS宏,这个宏如果大家不用自动生成的话,会发现它是自动生成的,根据字面上的意思是导出的意思。大家也不会太去关注它了,但是我想在这里说的是这个宏在dll文件里,起着非常重要的作用。一.它会判断是外部申明,还是内部申明如果是在dll中就用export,在应用程序就用import(这个是由编译器判断),二. DLL 中的所有文件都是用命令行上定义的 xxx_EXPORTS 符号编译的。并且XXX必须与项目名一致,否则报错,原因就是此DLL 中的所有文件都是用命令行上定义的 XXX_EXPORTS符号编译的,并且与windows内部机制和编译器定义有关。
#define JUNO_API __declspec(dllexport)
这个是导出dll函数(这里是使用MFC提供的修饰符号_declspec(dllexport)),这个是外部项目的引用 (XXX _declspec(dllexport)里面的XXX可以任意定义,只需要保证这个宏修饰这个宏修饰的类/变量/函数与其对应就ok,不过从变量命名角度上看,就与系统自动生成的规范命名就好)
#else
#define JUNO_API __declspec(dllimport)
内部库的引用
#endif
JUNO_APIvoid CALLBACK DllFoo(void);
.cpp文件
hmodle是库被调用的时候,传过来的指向自己的句柄
ul_reason_for_call库被调用的原因
lp就是系统保留的一个参数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:如果不是第一次调用,就不会再调用dllmain,只会曾加其次数
case DLL_THREAD_ATTACH:线程的调用,与最大的区别就是它会每一次重新掉用dllmain
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:在有freelib函数 或dll接触映射的时候被调用
break;
}
return TRUE;
}
JUNO_API void CALLBACK DllFoo(void)
{
MessageBox(NULL,TEXT("This function is exported from a DLL"),TEXT("DllFoo"),MB_OK);
return ;
}
其实 我为什么还要说这,因为我现在的3D引擎就是在这个代码的基础上建立起来的!也准备过段时间开源,也想准备连续讲解如何开发引擎的步骤!让中国在这个产业有更好的发展!