zoukankan      html  css  js  c++  java
  • 温故而知新我再一次学习库

    一个语言的活力,在于库的丰富与否!


    动态,静态库的发布和使用。这里给大家一个简单解释!要真正理解,得动手试试啊。
    动态指的是随时用随时调用,并没有加载到可执行程序里面,而是获得一个函数或者变量的地址。用的时候去沿着地址取。

    静态指的是不管你用不用都放那里。用你就用。不用也放那里。

    1.动态链接库:动态顾名思义,是在程序运行时候用到哪里调入那里的方式。
    对于动态库的应用(在windows上)主要两种方式。
        1.1自动导入。
       首先,我们来发布一个dll库,过程:VS 新建项目----->win32控制台------->dll  (过程简单就不截图了)
       这时候,你需要的是如何发布dll以及如何这里有一种发布dll的方法:(实现加减乘除)
    头文件:Mydll.h

     

    extern "C"_declspec(dllexport)int add(int i,int j);
    extern "C"_declspec(dllexport)int sub(int i,int j);
    extern "C"_declspec(dllexport)int mull(int i,int j);
    extern "C"_declspec(dllexport)float divv(int i,int j); 
     
    复制代码

    cpp文件:Mydll.cpp

    // jisuan.cpp: implementation of the jisuan class.
    //
    //////////////////////////////////////////////////////////////////////
    
    
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    #include "jisuan.h"
    int add(int i,int j)
    {
            return i + j;
    }
    int sub(int i,int j)
    {
            return i - j;
    }
    int mull(int i,int j)
    {
            return i * j;
    }
    float divv(int i,int j)
    {
            return i/(float)j;
    }


    点击生成,在debug文件下就有了一些东西 主要用的是 dll 和lib文件。
    这里先解释一下,这两个文件的作用。dll就是动态链接库,里面主要保存了所需要的函数以及数据。而lib文件呢?是动态库的引导库。在第二种方法:手动添加的时候使用不到它的。这里自动方法,用引导库自动在发布程序过程中将动态库里面的函数地址用引导库直接静态的放到可执行文件里。
         好的,接下来是动态库的编译与运行了。为什么要分着说呢?因为他们确实在分管着不同的时刻。在编译时是不需要动态库的,当然在运行时是不需要引导库的。   所以,你要知道即便静态库也是lib 他们本质上是不一样的(虽然作用都是静态的发布到可执行程序中)。
    接下来,我们简单新建一个win32控制台程序。
        首先,我们需要编译时候将dll中的函数地址在编译时候放到可执行程序中。
         所以设置项目属性(项目--->右键--->属性)
         C++常规中 附加包含目录中添加上你那个Mydll.h的地址。
         链接器---->常规----->附加库目录:你得Myddl.lib 的目录地址
         输入----->附加依赖项 : Mydll.lib
    ok,这个时候就可以像用 iostream 中的 cout一样用 你在Mydll中函数了
    比如:

    1 #include "stdafx.h"
    2 #include "jisuan.h"
    3 int _tmain(int argc, _TCHAR* argv[])
    4 {
    5         int a=2,b=3;
    6         int c=add(a,b);
    7         return 0;
    8 }

     

     

    编译可以了!运行肯定不行,你得add在dll里面呢,这时候把Mydll放到相应目录下面就行了。
    以上就是自动加载dll,其实多半的开源库都是自动加载的函数地址(不然要手动加载地址累死了)。

           1.2 下面说一下手动的方法:利用windows接口函数,寻找dll库中的函数地址,加载并应用。

     1 #include "stdafx.h"
     2 #include <windows.h>
     3 typedef int (*func)(int,int);
     4 typedef int (*func)(int,int);
     5         INSTANCE hdll=LoadLibraryA("Mydll2.dll"); //加载
     6         unc anotherAdd=(func)GetProcAddress(hdll,"add"); //获得地址
     7         //int a=5,b=7;
     8         int c=        anotherAdd(a,b);
     9          FreeLibrary(hdll);
    10         return 0;
    11 }

     

    这个就是两种加载动态的方法。
    2.静态库的应用  解释一下,静态库的优点就是运行的快,缺点是占用内存大。因为它所有的数据和代码都放到了可执行程序中。
          静态库的制作:
                      1.新建win32空项目。当然,要选择你要做静态库。
                      2.新建一个类 MathFuncsLib  
    MathFuncsLib.h

    namespace MathFuncs
    {
            class MyMathFuncs
            {
            public:
                    static double Add(double a, double b);
                    static double Subtract(double a, double b);
                    static double Multiply(double a, double b);
                    static double Divide(double a, double b);
            };
    }

    MathFuncsLib.cpp

    // MathFuncsLib.cpp
    // compile with: /c /EHsc
    // post-build command: lib MathFuncsLib.obj
    
    #include "MathFuncsLib.h"
    
    #include <stdexcept>
    
    using namespace std;
    
    namespace MathFuncs
    {
            double MyMathFuncs::Add(double a, double b)
            {
                    return a + b;
            }
    
            double MyMathFuncs::Subtract(double a, double b)
            {
                    return a - b;
            }
    
            double MyMathFuncs::Multiply(double a, double b)
            {
                    return a * b;
            }
    
            double MyMathFuncs::Divide(double a, double b)
            {
                    if (b == 0)
                    {
                            throw new invalid_argument("b cannot be zero!");
                    }
    
                    return a / b;
            }
    }


    编译运行 在debug里面就有了 一个文件    MathFuncsLib.lib
    接下来是 静态库的应用了。其实就像用刚才用引导库一样。(其实原理是一样的,只是这个静态加载的东西更多了)。
    c.png

    b.png

    a.png 

    好的,设置完了,你就可以用了(记得包含头文件以及命名空间an哦!!)

    把库的知识闹懂了,其实特别有用。至少对我来说,当我再去使用别人的库的时候,我会更轻松的理解和使用。

    当然,开发自己的程序是也可以采用这种方式,更加可靠和快速!欢迎指正。


    作者:leisure
    原文出自:http://www.cnblogs.com/leisure/
    感谢园子,感谢各位支持。本文版权归伟征和博客园共有,欢迎转载@ 但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    只是想分享,欢迎拍砖!促进我成长

  • 相关阅读:
    这一年来,我的初三
    LGOJP4381 [IOI2008]Island
    BZOJ4484: [Jsoi2015]最小表示
    二分图染色及最大匹配(匈牙利算法)略解
    2019牛客多校第三场 F.Planting Trees
    性能优化 | 30个Java性能优化技巧,你会吗?
    进程 | 线程 | 当Linux多线程遭遇Linux多进程
    性能面试 | 性能测试常见面试题
    性能调优 | 如何通过性能调优突破 MySQL 数据库性能瓶颈?
    性能分析 | Java服务器内存过高&CPU过高问题排查
  • 原文地址:https://www.cnblogs.com/leisure/p/2553176.html
Copyright © 2011-2022 走看看