zoukankan      html  css  js  c++  java
  • C++高级编程2. 静态动态链接库

    C++高级编程2. 静态动态链接库20131018

    1.动态链接库和静态链接库的区别:

        静态链接库就是把lib文件中用到的函数代码直接连接进目标程序,程序运行的时候不在需要其他的库文件;动态链接库是把调用的函数所在文件模块(对应的DLL)和调用函数在文件中的文职等信息链接进目标程序,程序运行的时候再从DLL中寻找相应的函数代码,因此需要响应DLL文件的支持。

        静态链接库和动态链接库都是采用共享代码的方式,如果采用静态连接,无论我们愿不愿意,lib中的指令都全部被包含在最终生成的EXE文件中。但是如果我们使用动态链接库DLL的话,改DLL文件不包含在最终的EXE文件中,而是单独的一些文件,和EXE一起发布,EXE文件执行的时候,会东热爱的引用和卸载这些和EXE独立的DLL文件。同时静态链接库中不能够在包含其他的动态或是静态的链接库,但是DLL中是还可以包含其他的动态或者是静态的链接库。

        每一个lib文件就是若干个函数的定义,lib库有两种,一种是包含了函数所在DLL文件和文件中函数位置信息,称之为导出库;一种是包含函数代码本身,一般现有的DLL,用的是前一种库。

        使用静态库比较简单,我们将函数作为一个extern  “C ” 编译生成响应的lib文件,然后再另一个工程中,#include 头文件,就可以使用使用了,在编译过程中,会将器提阿尼啊到最终的exe执行文件中;

    2.我们看一下创建动态链接库的例子。

    首先是看如何创建DLL,一般会按照C方式的编译而不是C++的链接方式。

    2.1创建DLL:新建解决方案和项目的时候,创建的是DLL项目而不是控制台,这样的话,最终编译生成的是DLL文件。创建完成空项目之后,创建两个文件一个是头文件(MathFuncs.h)这个头文件是声明函数的形式,到时候提供给使用者。

        头文件声明的形式:

    //MathFuncsDll.h

    #define MATH_FUNCS_API __declspec(dllexport)

    extern "C" {

        int MATH_FUNCS_API add(int a, int b);

        int MATH_FUNCS_API add(int a, int b);

    }

    这样表示对外的函数的形式 其中定义了一个,表示的是方式export导出函数的形式。然后在对应的CPP文件中实现对应的声明形式。

    //MathFuncsDll.cpp

    #include <iostream>

    #include "MathFuncsDll.h"

    using namespace std;

     

    int add(int a, int b){

        cout << "in dll add function" << endl;

        return a+b;

    }

    int sub(int a, int b){

        cout << "in dll sub function" <<endl;

        return a-b;

    }

    这样就编译就完成了对外输出的函数的DLL创建。

     

    在看一下应用程序,应用程序使用DLL有两种方式,一种是使用.h 头文件,然后直接调用其中的函数使用,但这种方式在程序一开始的时候就需要将所有的DLL全部加载到内存,占用了大量的资源;虽然比较直接,但是浪费了空间和效率。

    在 应用程序中调用使用的是

    MathFuncsDll.h

    #define MATH_FUNCS_API __declspec(dllexport)

    extern "C" {

        int MATH_FUNCS_API  add(int a, int b);

        int MATH_FUNCS_API  sub(int a, int b);

    }

    在程序中直接include 该头文件即可使用器对应的函数,在程序需要的时候,跳转到DLL中的地址执行。

     

    另外一种方式就是使用动态加载DLL的方式:

    不需要使用头文件,只要知道其函数的名字和参数类型,使用Windows.h中的动态加载。

    这一种方式更加常用,而且更加高端大气上档次,不过在VS中需要将项目的属性中的字符集设置成为更多的字符而不是Unicode字符集

        int a = 9, b= 3;

        HINSTANCE hInstance = LoadLibrary("MathFuncsDll.dll");

        if(hInstance != NULL){

            cout << "success load dll " << endl;

            Func add = (Func) GetProcAddress(hInstance,"add");

            if(add != NULL){

                cout << add(a,b) << endl;

            }

     

     

            Func sub = (Func) GetProcAddress(hInstance,"sub");

            if(sub != NULL){

                cout << sub(a,b) << endl;

            }

     

        }else{

            cout << "load dll failed" << endl;

        }

     

        if(hInstance != NULL){

     

            FreeLibrary(hInstance);

            cout << "free dll " << endl;

        }

    在看一下下静态库的加载和调用,因为静态库是需要链接形成二进制文件的,所以exe的会比较大,发布的时候,直接将exe发布即可,而不用dll

        静态库提供给别人使用的时候,应该有头文件,下面讲解一个例子

    创建一个解决方案,然后添加一个项目,是静态库的形式,是空项目,添加一个头文件和一个cpp文件:

    //sub.h

    extern "C" {   

        int  sub(int a, int b);

    }

    //sub.cpp

    实现函数

    在创建一个项目添加进解决方案

    创建一个main.cpp

    将该项目设置成为启动项目,并且添加引用的关系,(必须添加引用关系,否则报错);

    在cpp中

    #include <iostream>

    #include "../sub/sub.h"

    using namespace std;

     

    int main(){

        cout << sub(12,9) << endl;

        return 0;

    }

     

     

  • 相关阅读:
    【数论】错排问题
    【数论】求逆元的几种方式
    【数论】卢卡斯定理模板 洛谷P3807
    【单调队列优化dp】 分组
    【期望dp】绵羊跳弹簧
    软件工程总结
    结对项目-地铁出行路线规划程序(续)
    个人作业--week3
    个人作业-week2
    个人作业-week1
  • 原文地址:https://www.cnblogs.com/hbhzsysutengfei/p/3409478.html
Copyright © 2011-2022 走看看