• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > 静态库和动态库的生成和加载详解

静态库和动态库的生成和加载详解

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了静态库和动态库,动态库和静态库的区别,linux静态库和动态库,静态库转动态库,动态导入库和静态库等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

静态库和动态库的生成和加载详解


我们以前写C语言代码的时候,基本上都是要包含了对应的头文件,才能使用一些函数,比如我们使用printf函数的时候,最常用的就是stdio.h头文件,stdio.h中有我们printf的声明,它真正的实现是在我们的底层库中。
首先,我们先来看看什么是库?
库:函数库是实现了某一类功能的若干的函数和数据二进制代码的集合。
注意:库中虽然是函数的二进制代码集合,但不能独立执行,可以被载入内存,和其他程序结合起来执行。
Windows静态库:xxx.lib
动态库:xxx.dll
Linux静态库:xxx.a
动态库:xxx.so

我们这里所说的静态库和动态库指的是链接时刻不同。首先,我们来回忆一下编译的流程,我们让普通程序编译成可执行程序的步骤:预处理——编译——汇编——链接

其实前3个步骤是我们的基本C语言代码都需要运行的,生成xxx.o文件,最终向三个方向发展=>可执行文件、静态库或动态库。

一、静态库
静态库之所以叫静态库,是因为我们在编译的阶段,就把我们函数库的代码载入可执行文件中。由于整个函数库的所有数据都会被整合进目标代码中,那么它的优缺点就显而易见了。
优点:就是编译后的执行程序不需要外部的函数库支持。
缺点:就是生成的文件比较大,若是函数库的代码改变了,则需要重新编译。
特点:静态库的代码在编译过程中已经被载入可执行程序,因此生成的可执行程序体积较大。

下面介绍使用VS2008制作和调用静态库:
1.工程的建立——选择Win32项目,输入工程名

在应用程序设置中选择“静态库”选项

这样就完成了工程的创建。

2.添加两个文件,一个为lib.cpp,另一个为头文件lib.h。我们所编写的函数放在lib.cpp,而其原型放在lib.h。这两个文件的内容为:
  1. //lib.cpp
  2. #include "stdafx.h"
  3. #include "lib.h"

  4. int add(int x,int y)
  5. {
  6. return x + y;
  7. }
  1. //lib.h
  2. #ifndef LIB_H
  3. #define LIB_H

  4. extern "C" int add(int x,int y);

  5. #endif
注意:可能部分同学对“lib.h”中的extern “C”的表达形式有疑问,其实就是一种编译规约,其中extern是关键字属性,表征了变量、函数等类型的作用域(可见性)属性,该关键字告诉编译器它所声明的函数和变量可以在本模块或者文件以及其他模块或文件中使用;“C”表征了编译器链接规范。所以整体可以理解为C++/C中的混合编程的编译指令。
编译后,根据编译配置类型,可以在Release或Debug文件夹下即可查看编译后的结果。


3.下面看如何使用这个函数,新建一个控制台应用程序,并将“lib.h”以及生成后的“win32_Lib.lib”复制至新建工程的源文件夹下,再编写测试应用源程序如下:
  1. //test_Lib.cpp:定义控制台应用程序的入口点
  2. #include
  3. #include "lib.h"//函数原型声明

  4. #pragma comment(lib,"win32_Lib.lib");//将静态库导入

  5. int main()
  6. {
  7. printf("2+3 = %d",add(2,3));
  8. getchar();
  9. return 0;
  10. }
注意:可能部分同学也没见过“#pragma comment”,所以不知道是什么意思,其实“#pragma”指令是所有的预处理指令中最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。原声明为:#pragma comment(comment-type,"commentstring"),comment-type是一个预定义的标志符,指定注释的类型,应该是compiler,exestr,lib,linker之一;commentstring是一个为comment-type提供附加信息的字符串。
#pragma comment(lib,"win32_Lib.lib");表示链接win32_Lib.lib这个库。和在工程设置里写上链入win32_Lib.lib的效果是一样的,不过这种方法写的程序,别人在使用你的代码的时候,就不用再设置工程settings了

二、动态库
顾名思义,根据名字你就知道,我们动态库肯定是动态链接的。没错,我们的动态函数库在编译的时候并没有被编译进目标代码中,而是在运行的时候,才来链接我们函数库中要用到的函数。因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库,以及库路径。
特点:动态库的代码在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此可执行代码体积小。

下面介绍使用VS2008制作和调用动态库:
1.工程的建立——选择Win32项目,输入工程名win32_Dll
在应用程序设置中选择“静态库”选项

这样就完成了工程的创建。

2.添加两个文件,一个为win32_Dll.cpp,另一个为头文件win32_Dll.h。我们所编写的函数放在win32_Dll.cpp,而其原型放在win32_Dll.h。这两个文件的内容为:
  1. // win32_Dll.cpp : 定义 DLL 应用程序的导出函数。
  2. #include "stdafx.h"
  3. #include "win32_Dll.h"

  4. #defineEXPORTING_DLL

  5. int add(int x,int y)
  6. {
  7. return x + y;
  8. }
  1. //win32_Dll.h
  2. #ifndef WIN32_DLL_H
  3. #define WIN32_DLL_H

  4. #ifdef EXPORTING_DLL
  5. #define API_TYPE__declspec(dllexport)
  6. #else
  7. #defineAPI_TYPE__declspec(dllimport)
  8. #endif

  9. extern "C" int API_TYPE add(int x,int y);
  10. #endif
注意:可能部分同学也没见过“__declspec(dllexport)”和“__declspec(dllimport)”,所以不知道是什么意思,其实一个是提供者,一个是使用者,二者之间的接口是头文件。头文件中声明了方法,在提供者那里方法应该被声明为“__declspec(dllexport)”,在使用者那里,方法应该被声明为“__declspec(dllimport)”。二者使用同一个头文件,作为接口,使用条件编译:定义一个变量,针对提供者和使用者,设置不同的值。

编译后,根据编译配置类型,可以在Release或Debug文件夹下即可查看编译后的结果。


3.下面看如何使用这个函数,新建一个控制台应用程序,并将生成后的“win32_Dll.dll”和“win32_Dll.lib”复制至新建工程的源文件夹下,再编写测试应用源程序如下:
  1. #include
  2. #include

  3. typedef int (*lpAddFun)(int,int);//函数指针

  4. int main()
  5. {
  6. HINSTANCEhDll;
  7. lpAddFun addFun;
  8. hDll = LoadLibrary("win32_Dll.dll");//加载动态库
  9. if(hDll)
  10. {
  11. addFun = (lpAddFun)GetProcAddress(hDll,"add");
  12. if (addFun)
  13. {
  14. printf("2 + 3 = %d\n",addFun(2,3));
  15. }
  16. }
  17. getchar();
  18. FreeLibrary(hDll);//卸载动态库
  19. return 0;
  20. }
注意:可能部分同学也没用过“函数指针”,所以对着段代码不好理解,可以参考我之前写的这篇博客:http://blog.chinaunix.net/uid-31439230-id-5763256.html;
LoadLibray()函数载入指定的动态链接库,并将它映射到当前进程使用的地址空间,一旦载入,即可访问库内保存的资源;
GetProcAddress()寒山寺检索指定的动态链接库(DLL)中输出库函数地址,如果函数调用成功,返回值是DLL中输出函数地址,失败,返回值是NULL。



分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 静态库和动态库的生成和加载详解

相关文章

  • 2017-05-26Android对话框,android弹出对话框
  • 2017-05-26Android开发学习—— Broadcast广播接收者,androidbroadcast
  • 2017-05-26解决Android后台清理APP后,程序自动重启的问题,androidapp
  • 2017-05-26NDK中使用pthread多线程中自己写的一个BUG,ndkpthread
  • 2017-05-26玩转Android---事件监听篇---第2篇,android---第2篇
  • 2017-05-26Android IPC机制(四):细说Binder连接池
  • 2017-05-26mongodb3.0.7生产环境扩容存储记录
  • 2017-05-26Android设置透明状态栏和透明导航栏,android导航栏
  • 2017-05-26Android studio .gitignore 文件的内容,android.gitignore
  • 2017-05-26Android Layout XML属性,androidlayout

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 手机影音2--软件架构分析,影音2--架构分析
    • Android 高仿华为手机Tab页滑动导航效果
    • Android之TextView,androidtextview
    • Activity的生命周期,Activity生命周期
    • [转载] 从Handler.post(Runnable r) ,Handler.sendEmptyMessage()梳理Android的消息机制(以及handler的内存泄露),
    • 使用ContentProvider访问非数据库数据
    • android四大组件之Broadcast,androidbroadcast
    • 安卓学习----使用okHttp(get方式)---下载图片,
    • android studio我的习惯操作,androidstudio习惯
    • 7.6.1 Socket学习网络基础准备

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有