zoukankan      html  css  js  c++  java
  • 调用静态函数库(lib)和动态函数库(dll)

    1.什么是静态链接库
    静态库(Static Library)通常包含一堆程序员自定义的变量与函数,在编译期间由编译器和链接器将它集成到可执行文件中,也就是生成的.exe文件中

    2.静态库的扩展名
    在Windows下,静态库的扩展名是.lib,在Linux下是.a

    3.静态库的优缺点
    1)优点:

    发布时只需发布.exe文件,因为库已经集成到可执行文件中,运行时不再依赖库

    2)缺点:

    静态库集成到.exe文件中,导致.exe文件较大,同时,如果后续想要升级库必须重新编译.exe文件。

    生成静态库的过程源码中可以没有main()函数的,调用时只需要链接这个lib库即可,完成lib内部
    函数的调用。

    2.动态链接库:

    可以生成动态链接库供外部(如exe)调用。

    生成时,源码内需要在你允许对方显示调用的函数的定义前加上前缀__delsec(dllexport)。这样便会输出,.dll和.lib。

     1 #include "func.h"
     2 #include "stdafx.h"
     3  
     4 extern "C" _declspec(dllexport) int SquareSum(int a, int b)
     5 {
     6     return (a*a + b * b);
     7 }
     8  
     9 extern "C" _declspec(dllexport) int SumSquare(int a, int b)
    10 {
    11     return ((a + b)*(a*b));
    12 }

    然后调用的时候又有两种方式,显示调用和隐式调用。

    显式调用:达到和函数定义在本文件中的效果一样,不需任何变化。(一般还是显示调用更普遍

    • 将.lib添加到工程的附加依赖,然后将dll拷到exe文件附近,先用extern __delsec(dllimport)声明我要从外部导入这个函数。就可以任意调用其中的函数了。lib中记录了函数在dll内的位置
       1 #include <iostream>
       2 using namespace std;
       3 #include "func.h"
       4  
       5 #pragma comment(lib,"DynamicLib32.lib")
       6  
       7 int main()
       8 {
       9     int a = 34;
      10     int b = 32;
      11     cout << SquareSum(a, b) << endl;
      12     cout << SumSquare(a, b) << endl;
      13  
      14     system("pause");
      15     return 0;
      16 }

      还需要给调用添加声明此为外部调用的函数的头文件。 

      #pragma once//调用时要给编译器声明这是调用的外部函数
       
      extern "C" _declspec(dllimport) int SquareSum(int a, int b);
       
      extern "C" _declspec(dllimport) int SumSquare(int a, int b);

    隐式调用:通过包含window.h,用系统来调用。先声明指针,然后指针通过系统API去dll内部去找这个函数。

     1 { 
     2 HINSTANCE   hDllInst   =   LoadLibrary( "youApp.DLL "); 
     3 if(hDllInst) 
     4 { 
     5 typedef   DWORD   (WINAPI   *MYFUNC)(DWORD,DWORD); 
     6 MYFUNC   youFuntionNameAlias   =   NULL;   //   youFuntionNameAlias   函数别名 
     7 youFuntionNameAlias   =   (MYFUNC)GetProcAddress 
     8 (hDllInst, "youFuntionName "); 
     9 //   youFuntionName   在DLL中声明的函数名 
    10 if(youFuntionNameAlias) 
    11 { 
    12 youFuntionNameAlias(param1,param2); 
    13 } 
    14 FreeLibrary(hDllInst); 
    15 } 
    16 }

    3.为何多用显式调用的动态库? 

    • 静态库打包很大;然后如果库改变了,那使用库的程序需要重新编译,因为这个库已经融进程序中了。
    • 动态库很小,同时多出调用一个函数,可共享只会加载一个;如果库改变了,只需要了用新的dll替换即可,只要接口不变,就不需要改动使用动态库的程序
  • 相关阅读:
    反射的基础详解
    数组,排序,枚举
    继承,多态,抽象,接口
    视图层 view
    常用类Object,String类详解
    模板层 Template
    自定义注解
    Django 高级
    常用类Math,StringBuffer,包装类,Date
    内部类,异常
  • 原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12725201.html
Copyright © 2011-2022 走看看