• DLL编辑使用分析(原创)


    一 编写动态链接库DLL

    DLL简称动态链接库,是Windows中程序的重要组成部分。

    在DLL工程中编写如要定义的函数,并用extern "C" __declspec(dllexport) 声明,如下所示:

    extern "C" __declspec(dllexport) __stdcall int add(int,int);

    extern "C" __declspec(dllexport) __stdcall int sub(int,int);

    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
            return 1;
    }
    ////---------------------------------------------------------------------------
    __declspec(dllexport) __stdcall int add(int a,int b)
    {
      return a+b;
    }

    __declspec(dllexport) __stdcall int sub(int a,int b)
    {
      return a-b;
    }

    因为需要在客户程序中进行调用,所以DLL中所写的函数我们称之为导出函数

    编译工程会生成一个.lib文件和一个.dll文件。

    注:

    1、之所以用extern "C" 是因为C编译器把人写的函数名当成函数名,而C++编译器把人写的函数名做了改动之后当成函数名为了让c++编译器不改动函数名,就加上extern "C" 。

    2、dllexport一般指函数被导出,dllimport指函数被导入,在实际测试的时候并不影响程序运行。


    二 静态调用动态链接库DLL 

    静态调用需要.LIB库文件和.DLL文件,程序编译时,需要用到.LIB文件,发布时这个LIB文件就不再需要。而且,编译系统时,这个动态链接库已编译进程序,这样,在程序一开始运行时就会查找这个DLL文件,如果这个DLL文件不存在,那么,程序是启动不起来的。除了这两个文件外,静态调用还需要导入函数。

    TFormMain *FormMain;

    extern "C" __declspec(dllimport) int __stdcall add(int a,int b);//导入函数
    extern "C" __declspec(dllimport) int __stdcall sub(int a,int b);//导入函数

    //---------------------------------------------------------------------------
    __fastcall TFormMain::TFormMain(TComponent* Owner)
    : TForm(Owner)
    {
    int rslt = add(1,2);

    }

    程序输出rslt=3;

    1、导出函数和导入函数在格式上必须保持一致;导出一般放到头文件中进行引用。因为编译器在编译的过程中本来的一个add函数,如果什么标识符也不加会被变异成add;加了extern "C",会被命名为?add@@YAHHH@Z,再加上__stdcall就会被命名为_add@。所以如果导出函数和导入函数格式不一致就因为函数名不同而引起程序无法找到DLL中的函数从而出现错误。

    三 动态调用动态链接库DLL 

     动态调用DLL,只需要.DLL文件,程序运行时,程序不需要知道这个DLL文件当前是否存在,只有当程序运行到某个点,才需要去调用DLL文件多个应用程序调用DLL时,DLL 在内存中只产生一个实例,因此,可以有效地节省内存空间,提高系统的运行效率。

    动态调用DLL函数可分为八步:
    第一步:函数定义。这里的函数为地址转换函数。下面这个函数其实就是定义 int __stdcall add(int,int);
       int __stdcall (*myadd)(int,int);
    第二步:定义模块句柄,全局变量,它是载入DLL文件后的实例
       HINSTANCE HmyDLL;
    第三步:装入DLL文件,同时获得它的句柄
      HmyDLL=LoadLibrary("myDLL.dll");
    第四步:获取动态链接库内的某一函数的内存地址
      (FARPROC &)   myadd = GetProcAddress(HmyDLL,"add");
    第五步:函数调用
      n=myadd(10,20);
    第六步:释放DLL
      FreeLibrary(HmyDLL);

    TFormMain *FormMain;
    //---------------------------------------------------------------------------
    __fastcall TFormMain::TFormMain(TComponent* Owner)
    : TForm(Owner)
    {
    int rslt;
    int (*myadd )(int,int);
    HINSTANCE HmyDLL= ::LoadLibrary("myDLL.dll");
    (FARPROC &) myadd = GetProcAddress(HmyDLL,"sub");
    rslt = myadd (2,8);

    FreeLibrary(HmyDLL);
    }

  • 相关阅读:
    离线语音
    云知声语音开发
    自定义View -- 柱状图 我也来自定义个柱状图来玩玩
    android studio中如何替换gradle以防下载卡住
    如何查询当前手机的cpu架构,so库导入工程又出异常了?
    android 学习mvc 和 mvp 和 mvvm参考项目
    【整理】Android中EditText中的InputType类型含义与如何定义( 转 )
    Android点击EditText文本框之外任何地方隐藏键盘的解决办法
    Android开发 adb命令提示:Permission denied (转)
    Node.js-串行化流程控制
  • 原文地址:https://www.cnblogs.com/geowu/p/7155056.html
Copyright © 2020-2023  润新知