DLL创建与使用方法浅谈(2)

一、动态链结库的动态加载简介

    DLL创建与使用方法浅谈(1中为通过引入库(.lib)文件和声明文件使用DLL的方法,本博文介绍的为动态加载DLL文件。无需引入库,也无需声明。动态的加载DLL库函数内容。


二、DLL创建和动态加载方法(运行时动态链接

     步骤1DLL中函数创建

        file1.cpp---------------------------------------------------

       int Add(intx,int y)

       {

               return x+y;

       }

       int Subtract(intx,int y)

       {

               return x-y;

       }

 

     步骤2、导出内容声明文件创建

       file2.def---------------------------------------------------

       //以使得其他语言编制的程序也能使用我们的动态链接库。

       LIBRARY  Dll2 (可选项)

       EXPORTS //导出关键字

               Subtract  //函数名1

               Add     //函数名2

 

       //即使调用_stdcall约定,也不会发生改编,而只会调用这里显示的Add字符串

       更名导出及和数字编号指定。导出 definitions 的语法为:

       entryname[=internalname][@ordinal [NONAME]] [PRIVATE] [DATA]

 

       步骤3EXE动态引用关键代码

        HINSTANCE hInst;

        hInst=LoadLibrary("Dll2.dll"); //使用动态加载


        typedef int (*ADDPROC)(int a,int b);

       //如果在DLL的函数中调用_stdcall,相应的应该把代码改为

       //typedef int(_stdcall *ADDPROC)(int a,int b);  //注意到处函数的调用约定

        ADDPROC Add=(ADDPROC)GetProcAddress(hInst,"Add");//构造一个函数指针

        if(!Add)

        {

              MessageBox("获取函数地址失败!");

              return;

        }

        CString str;

        str.Format("3+5=%d",Add(3,5));

        MessageBox(str);

 

       因为调用LoadLibrary时动态加载动态链接库,所以不需要头文件和.lib文件

 

       如果我们在动态链接库中使用标准调用约定_stdcall,而在可执行程序中使用动态加载DLL,会发生名字重编,如果知道DLL中函数的序号,这时可以使用宏MAKEINTRESOURCE把序号转变成名字,如:

ADDPROCAdd=(ADDPROC)GetProcAddress(hInst,MAKEINTRESOURCE(1));


三、与DLL有关重要函数的介绍

             BOOL WINAPIDllMain(  HINSTANCE hinstDLL,  DWORD fdwReason,  LPVOID lpvReserved);

       需要WINDOWS系统传入参数时使用上面函数。

      DllMain是DLL的入口与出口,进行初始化与退出处理。如果初始化成功应返回TRUE。


            BOOLFreeLibrary(  HMODULE hModule);

       当我们的动态链接库不再使用时可以调用FreeLibrary使动态链接库使用计数减1,当使用计数为零时,系统会收回模块资源。


          LoadLibrary(szDll):加载szDll,返回HANDLE。加载成功后可以用GetProcAddress(hLibrary,szFunction)获得函数地址,或用LoadBitmap等加载资源。


四、DLL共享内存功能简介

      动态链接库分配的内存空间由应用程序所有,不同的应用程序调用相同的DLL数据不同。如果想要的数据内存在不同的应用程序或同一应用程序的不同实例之间共享,就要用到共享内存,实际上是一个内存映射(Memory-mapped)文件。在#prama data_seg("shared")与#pragma data_seg()之间定义的变量都可共享,但必须要初始化,否则编译器会把变量定义在未初始化数据区,而不是"shared"。“shared”是数据区名称,可以随意取。为共享数据,还要修改链接器命令,加上“/SECTION:shared,RWS”参数,或者在源文件中加入链接命令#prama comment(linker,"/SECTION:shared,RWS"),告诉链接器shared数据区有读写共享属性。

例:

#pragma data_seg("shared")
TCHAR buffer[30] = "HELLO WORLD!";
#pragma data_seg()
#pragma comment(linker, "/SECTION:shared,RWS")

// R  read    W  write   S   Shared


五、DLL资源

       在动态链接库中可以加载资源(图标、字符串、位图等)。如果从该库中加载,需要自己的实例句柄(DllMain的hInstance参数);如果从调用它的EXE文件中加载,则需要程序实例句柄。

在动态链接库中注册窗口类或创建窗口有些麻烦。这两个功能都要用实例句柄,如果使用动态库的句柄,窗口消息仍然通过调用它的程序窗口。所以如果必须要这样,最好使用调用它的实例句柄。由于模态对话栻在消息循环之外,DialogBox可以用动态库的实例句柄。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值