zoukankan      html  css  js  c++  java
  • 动态链接库--靠谱

    1.什么是动态链接库
    动态链接库(Dynamic-Link Library)通常包含程序员自定义的变量和函数,可以在运行时动态链接到可执行文件中

    2.动态库扩展名
    Windows下是.dll,Linux下是.so

    3.Windows系统动态链接库
    Windows操作系统核心有三个动态链接库(Kernel32.dll、User32.dll、Gdi32.dll),这些动态链接库构成了Win32 API函数

    4.动态链接库的优点
    1)节省内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本

    2)可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序

    3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数

    5.动态链接库的缺点
    DLL地狱(DLL HELL)

    6.创建动态链接库
    1)创建DLL项目

    2)添加.h头文件和.cpp文件

    和静态库的写法一样

    在.cpp中:

    #include "func.h"
    #include "stdafx.h"
     
    int SquareSum(int a, int b)
    {
        return (a*a + b * b);
    }
     
    int SumSquare(int a, int b)
    {
        return ((a + b)*(a*b));
    }


    在.h文件中:

    #pragma once
     
    int SquareSum(int a, int b);
     
    int SumSquare(int a, int b);


     这种情况下,我们点击生成,发现的确生成了一个.dll文件,但是没有.lib文件,如果我们用Dependency打开这个.dll文件,发现这个动态库是一个空文件,里面什么函数也没有

    3)使用extern “C” 和_declspec(dllexport)

    在.cpp里面的每个函数前面添加:

    extern "C" _declspec(dllexport)


     完整的就是:

    #include "func.h"
    #include "stdafx.h"
     
    extern "C" _declspec(dllexport) int SquareSum(int a, int b)
    {
        return (a*a + b * b);
    }
     
    extern "C" _declspec(dllexport) int SumSquare(int a, int b)
    {
        return ((a + b)*(a*b));
    }


    这样就生成了.lib文件和.dll两个文件

    自己在VS2017中测试只在函数实现的地方加了 extern "C" 和_declspec(dllexport),并没有在函数声明的地方添加它,得到了两个文件;也测试了在函数实现和声明的地方都添加它,得到了两个文件;但如果只在函数声明的地方添加它而不在函数实现的地方添加,这样便还是只得到了.dll文件而没有.lib文件

    4)生成.lib和.dll文件

    7.使用动态链接库
    1)创建一个应用程序项目

    2)编写程序在.cpp中:

    #include <iostream>
    using namespace std;
    #include "func.h"
     
    #pragma comment(lib,"DynamicLib32.lib")
     
    int main()
    {
        int a = 34;
        int b = 32;
        cout << SquareSum(a, b) << endl;
        cout << SumSquare(a, b) << endl;
     
        system("pause");
        return 0;
    }


    .h中(.h文件可以从生成dll项目中拷贝过来,但需要注意下面几点):

    #pragma once
     
    int SquareSum(int a, int b);
    int SumSquare(int a, int b);



    如果在.h中直接这样,便会编译错误:


    处理办法,在函数声明的地方加上extern “C”

    #pragma once
     
    extern "C" int SquareSum(int a, int b);
     
    extern "C" int SumSquare(int a, int b);


    但是这样方法也不是最好的,建议加上_declspec(dllimport),虽然它可以省略,但它可以提示编译器这个函数是从外部dll中导入的,有利程序的编译:

    #pragma once
     
    extern "C" _declspec(dllimport) int SquareSum(int a, int b);
     
    extern "C" _declspec(dllimport) int SumSquare(int a, int b);


    如果是从dll项目中直接拷贝过来的.h头文件中是:extern "C" _declspec(dllexport),发现也会编译正确,但不建议这样,建议改成上面的形式,把export改成import

    3)添加.lib文件,dll项目不仅会生成.dll文件也会生成一个“配套”的.lib文件,简单理解,这个文件记录了dll中函数的入口地址,所以要像静态库中的.lib文件一样,用同样的两种方式把它加到我们的项目中,具体方法看静态链接库的生成和使用

    添加好后,直接运行会得到错误:

    4)添加.dll文件。把.dll文件添加到项目的.exe同一个路径下

    这时运行便会得到正确结果:

    8.注意
    1)可以修改.lib文件的文件名,只要在项目引用它时,使用它目前的名称,便可以正确运行,但不能改变.dll文件的名字,不然也会出现找不到.dll文件的错误

    2).dll文件必须和.exe放在一起,.exe文件在哪里.dll文件也得在那里,两者“共存亡”,否则就会出现找不到.dll文件的错误

    3)和静态库一样,.dll文件也要和应用程序的位数相对应,要么都是64位的,要么都是32位的,不可交叉使用,否则出现:

     
    --------------------- 
    作者:深山里的小白羊 
    来源:CSDN 
    原文:https://blog.csdn.net/qq_33757398/article/details/81545966 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    Higher you climb, more view you will see.
  • 相关阅读:
    JSON和JSONP
    微信问题汇总
    Linux 技巧:让进程在后台可靠运行的几种方法
    redis笔记
    php安装
    数据库分享一: MySQL的Innodb缓存相关优化
    nginx是以多进程的方式来工作的
    运行和控制Nginx
    nginx安装
    Redis监控技巧总结
  • 原文地址:https://www.cnblogs.com/yyfighting/p/12500643.html
Copyright © 2011-2022 走看看