游戏开发

本类阅读TOP10

·初学者的福音:游戏开发新手入门指南
·《学VC、编游戏》重点算法解疑·快一点
·Windows的消息机制与消息重定向技术
·《学VC、编游戏》重点算法解疑·再快一点
·Rogue Guide
·《学VC、编游戏》重点算法解疑·狩猎谋生
·通向天才之路 : 把模块塞到动态连接库里去
·完成端口的深入理解及一种变态用法
·DirectX 9.0 SDK 开发包下载(April 2005)
·在OpenGL中实现多纹理混合(Multi-texture Blending)

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
通向天才之路 : 把模块塞到动态连接库里去

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站


通向天才之路 : 把模块塞到动态连接库里去

    你还在用静态链接库生成一个巨大的EXE文件吗?过时了,换动态链接库吧。其中的好处被微软说了一大堆,我就不在这里废话了。说实话,这样做没什么好处,只是大家都这样做,我也跟着就这样做,仅仅如此。

    为此,在下特意看了一些资料,微软那帮人的资料虽然详细,但是实在是罗嗦。唉,不如拉个人来问问来的快,呵呵。

    说回正题,微软的DLL标准可真是麻烦,除了标准的C/C++外还有MFC DLL和扩展的MFC DLL,汗~~。不过我只对写标准C/C++的DLL感兴趣。其实这个接口也很简单,在DLL那边只需要在函数声明前加一个前缀,就可以在主程序中得到这个函数的入口地址了,之后想干什么都可以。具体的做法如下:

    // 输出函数的前缀
    #define  DLL_EXPORT   extern "C" __declspec( dllexport )

    DLL_EXPORT VOID Func()
    {
        ...
    }

    简单吧?这样DLL这边就搞定了,你还可以输出类和全局变量,但是我是不需要了。

// 输出类的前缀
#define  DLL_CLASS_EXPORT   __declspec( dllexport )

// 输出全局变量的前缀
#define  DLL_GLOBAL_EXPORT   extern __declspec( dllexport )


    之后是EXE这边,虽然多了点东西,不过还是很简单的。第一件要做的事情是LoadLibrary,把要想要打开的DLL载入。

    HINSTANCE hInst = NULL;
    hInst = LoadLibrary("Render.dll");

    if (!hInst)
    {
        MessageBox(g_hWnd,"无法加载 Render.Dll ","Error",MB_OK);
    }

    还记得上面我声明的那个Func()函数吗?我不能直接得到那个函数,但是可以把那个函数的地址取出来。其实函数地址使用起来和函数是一样的。只不过,为了使用方便,需要定义一个函数指针的类型。如果要指向上面的那个Func(),则它的函数指针的类型定义如下:

    typedef void (CALLBACK* LPFUNC)(void)

    之后需要做的是声明一个指针,然后得到DLL中Func()的地址。GetProcAddress函数的第一个参数是之前得到的DLL的实例句柄,后面一个是DLL中那个函数的函数名。
      
    LPFUNC pFunc = NULL;
    LPFUNC pFunc = (LPFUNC)GetProcAddress(hInst, "Func");

    OK,到此为止已经差不多完成了,只欠最后一步调用那个函数:
   
    pFunc();


    以上的知识是基础中的基础,接下来才是技巧所在,所以一定要认真看哦!
-----------------------------------------------------------------------------

    你一定想过把整个渲染模块制作成一个对象,然后得到这个对象的指针后就可以任意渲染了。如果全部写成代码,那无疑是最快捷的,但是缺点是很会暴露细节给不要或者你不希望的人看到,甚至于拿到了整个渲染模块的代码,这是相当可怕的。当然你也可以制作成静态链接库(Lib),这无疑是个不错的想法,但是缺点也是非常明显的。你可能会发现在发布版本中想替换调其中一些部分是不可能的,而对开发者而言使用静态链接库则更苦:他不得不使用你所用得编译器或是相关的开发环境。哦~天哪,这对于我而言也是个不小的麻烦,我想用GCC编译我的主程序,因为我想试试我刚拿到的一个新的十分小巧的集成开发环境:Relo v0.99。而可恶的微软却只提供了VC编译器的Lib,迫使我不得不使用VC来开发图形渲染模块。所以我也就不得不做好写DLL的心里准备。

    于是我动手干了。我做了许多打算,最后发现最简单的方法是最好的方法。所以我按照我最原始的本能开始设计我的DLL。我做了一些限制:这样让程序看起来比较简单,条理也较为清楚。我规定每个DLL引擎对象都需要有一个ID来标识,以及DLL中唯一的接口函数:GetEngineObject。它的作用就是向主EXE程序返回一个DLL中与所给ID相对应的对象的地址。只要你愿意,你可以通过这个函数得到所有在那个DLL中的对象的地址。我想,这样的限制应该不过分吧。

    对于主EXE来说,要做的事情就是像上面的那些代码一样,得到GetEngineObject函数的地址,然后导出全部EXE需要的引擎对象。对于DLL来说,则需要解决一个如何让GetEngineObject得到引擎对象地址的问题。这个问题其实也不难解决,只要在引擎对象中声明一个全局的队列,当创建了一个需要暴露给EXE的引擎对象的时候,把它的地址和相对应的ID写到这个全局的队列中。而当主EXE调用GetEngineObject的时候,GetEngineObject就到这个全局队列中查找给它的ID,并返回对应的地址。实现一个队列我想对各位看官来说并不难吧,呵呵。

    OK,你的程序现在已经可以得到DLL中的对象了,现在你可以放心的把你的DLL交给需要它的人了。




相关文章

相关软件




月光软件源码下载编程文档电脑教程网站优化网址导航网络文学游戏天地生活休闲写作范文安妮宝贝站内搜索
电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

月光软件站·版权所有