`
Dustin
  • 浏览: 314660 次
  • 性别: Icon_minigender_1
  • 来自: 广州/成都
社区版块
存档分类
最新评论

C/C++库文件简介

阅读更多

   最初发表在这里

 

   其实,C/C++世界开始时并没有库这个概念,我们编写程序的时候,都是自己搞定一切:Coding,Compile,Link,生成一个可执行文件后载入系统运行就可以了。但是,如果每个程序员都这样各自为政的话,将会导致大量的重复劳动。譬如,在很多程序中都需要输入输出的功能,按照现在这种状况,只有每个程序员都自己重新开发这样的功能模块,这样效率之低下可想而知。于是,大家渴望能够进行代码重用:一些通用的代码最好能够由别人提供,我只需调用即可。
   那么,我们如何得到这些可重用的代码呢?首先我们想到可以让编译器自动为我们生成这些代码。我们只需调用这些函数,编译器解析到这些函数时,如C语言的 printf函数,则自动为我们生成相应的代码。嗯,确实是个可行的办法。Pascal中的一些标准方法就是这样提供的。但是,这个方法也有很大的缺陷:第一,就是大大加重了编译器的负担,使编译器复杂化,对于C语言这样的标准方法很多的语言更是如此。第二,很难对这些方法进行添加或者更新,如果有这样的需要,则只能重新编写和编译整个编译器。
   第二个方法就是将所有的标准函数都编译到一个可重定位模块中去,譬如,我们可以将printf,scanf等标准函数统一编译到一个libc.o文件中,然后,我们就可以把它连接到我们的程序中去。这个方法对于程序员来说相当方便,因为我们只需要指定一个连接模块就可以使用各种函数了。但是,对于计算机来说,这并不是一件好事:它太庞大了!如果我的程序中仅仅需要其中一个printf 函数,我也必须得把整个libc.o连接进去,而这个libc.o的大小通常都是以M为单位的,成本太高了,不可行。
    那好,如果这样空间成本太高的话,我们可以将其化整为零,每个方法编译成一个.o文件,譬如printf.o,scanf.o等等。对,这样一来,计算机是满意了,但是我们程序员却惨了:你想想,如果我在应用程序中使用了30个函数,那么我在连接的时候,需要准确无误地提供这三十个函数对应的.o文件,痛苦啊!
   有没有一个两全其美的方法,既能够减少对内存的占用,又方便程序员使用呢?有,静态库(static library)就是这样一个解决方案。静态库是一个或多个.o文件的集合。程序员使用到这些.o文件对应的函数时,只需要在连接时提供该静态库即可,而不需要列举用到的.o文件。而连接器进行连接的时候,只会将程序中用到的函数对应的.o文件连接到程序中。譬如,我们有一个库文件libc.a,里面放有printf.o,scanf.o等多个.o文件,如果我们程序中只使用了printf函数,那么,连接器只会将printf.o连接进来,而不会把scanf.o也连接进来,虽然它们都同在一个库文件中。这样,计算机和程序员都满意了。下图( from Apple )是使用静态库的示例:
static library

    那是不是有了静态库以后就万事大吉了呢?当然不是,静态库是在编译阶段跟应用代码连接在一起的,从那以后,两者就紧密耦合在一起。这样一来,应用代码中库文件的更新就成了大问题了。如果库文件更新了,我想在应用程序中使用到最新的静态库,那么,我只能够将我的代码跟新的静态库重新编译一次,很难维护。此外,静态库的性质使每一个应有程序都有静态库中相应部分的拷贝,譬如,程序A和B都用到了printf函数,那么在两个程序中都会有printf.o拷贝。如果系统中有好几十个进程都使用到了printf函数,那么相同的代码将会重复出现几十次,这对于内存是极大的浪费。针对这些问题,共享库(shared library,也叫做动态连接库,*nix中为so文件,Windows中称为Dll)诞生了。使用该技术,一个共享库只会在系统中出现一次,而不管系统中有多少个进程使用到这个共享库。同时,共享库中的代码段还可以被各个进程所共享。共享库的示例图(from Apple)如下:
dynamic library

     共享库是在应用代码装载到系统中的时候由动态连接器动态加载到内存空间去的。静态连接器在编译阶段只是在应用代码中插入一些关于共享库的基本信息,而不会将共享库的实际代码连接到应用代码中去。这样,如果库文件更新了,我们只需要重新启动应用程序,就可以使用到最新的库文件了,同时,我们还大大节省了内存,一举两得。
     现在,一切都那么美好,但是并非完美。现在的情况是在加载过程中我们会把应用代码中的使用到共享库动态加载到系统中,但是,这个库在实际运行过程中会被使用到吗?看下面例子:

void show(int cmd)
{
      if( cmd == 0 )
    {
        //use library method
     }
}

    如果传入的参数不等于 0 的话,libraay method是永远都不会执行的,但是,我们却会把这个共享库加载到系统中去。如果我们能够在运行过程中决定是否加载一个共享库,那该多好啊!完全可以,Linux以及相关系统我们提供了相关的API,这些API包含在头文件<dlfcn.h>中。相关的函数有:

void *dlopen(const char *filename, int flag);
void *dlsym(void *handle, char *symbol);
int dlclose (void *handle);
const char *dlerror(void);

    在VC,也有相应的函数完成相关功能。此外,VC中还有延迟加载技术,使得Dll可以按需加载。

补充一段共享库存在的问题:from [4]

DLL Hell

While it is usually a good idea to share a single instance of a library rather than reduplicate it into every individual program, this sharing can become a serious problem. Think of two different Web browsers that reside on the same machine. Both browsers use the same shared libraries to access the system's modem, graphics card, and I/O routines. Now, suppose that you recently had to install an update of one of these shared libraries because of a security loophole found in the original version. Alas, the new version causes one of the browsers to crash. You can either wait for a new patch or revert to the previous version of the shared library.

None of these workarounds is ideal. Had the library been statically linked into each browser application, this mess would have been avoided. Unfortunately, such conflicts are reconciled only when you explicitly enable multiple versions of the same shared library to coexist on the same machine. However, this workaround complicates system management and forces users to become experts. In the Windows world, this problem is called the "DLL hell" although it exists in the POSIX world too.

Aliasing

 

Dynamic linking enables you to share identical code, which is usually a good idea. However, sharing the same data is rarely desirable.

If, for example, two processes call localtime(), it must return a different local static tm struct for every process. Designers of dynamically linked libraries were aware of this necessity and devised various techniques to cope with it. However, programmers must explicitly state which components of a shared library are truly shared and which ones aren't. The result is a larger and slower shared library as well as cluttered-up source files.

Code Cracking

Windows programmers who wish to thwart crackers' attempt to decompile their code often split an application into multiple DLLs. Ironically, this makes a cracker's job much easier because DLLs (and shared libraries in general) must contain metacode, i.e., code that documents code. This metacode (reminiscent of debug information) tells the runtime linker where each function and object is stored in the file, what their non-decorated names are, and so on. A hacker that knows how this information is encoded can decompile the code with less effort than required for decompiling an optimized, statically linked executable

Reference:
[1] Computer Systems: A Programmer's Perspective,Chapter 7 Linking
[2] Program Library HOWTO
[3] Overview of Dynamic Libraries , Apple
[4] Dynamic Linking: Advantages and Disadvantages

分享到:
评论

相关推荐

    zlib.h(c/c++库文件)

    zlib.h c++/c库文件 zlib.h c/c++库文件

    MATLAB模糊控制器(*.fis)C/C++接口文件

    * 4、如果是C语言文件(*.c)使用 * #include "fis.c" * 包含接口库文件; * 5、如果是C++文件,使用 * extern "C"{ * #include "fis.c" * } * 包含库文件。 * 祝你使用愉快! * hemmingway ...

    C/C++ DevTools Support (DWARF)

    在本例中,C/C++ DevTools Support (DWARF)的crx文件意味着这是一个为Chrome浏览器定制的开发者工具,它扩展了浏览器的内置调试功能,使得在浏览器环境下调试C/C++ WebAssembly代码更为方便。安装crx文件通常需要在...

    C/C++ 标准库函数 (中文版)

    C/C++标准库函数手册是C/C++程序员必备的参考资料,它详细地介绍了C/C++语言中各种标准库函数的用途、语法和使用方式。标准库中包含了输入输出处理、字符串操作、数学计算、时间日期处理、内存管理等函数,此外C++...

    IAR C/C++ Development Guide

    编译是将C/C++源代码转换成机器代码的过程,链接则是将编译后的代码与库文件等其他模块合并成最终的可执行文件。IAR的ILINK工具提供了链接功能,同时指南还介绍了DLIB运行时环境的使用和汇编语言接口的处理。 知识...

    m文件转换为C,C++文件

    其中一种较为推荐的方法是使用 `mcc` 命令将 `.m` 文件编译为头文件、动态链接库 (DLL) 和库文件 (LIB),然后再将其导入到 VC++ 中进行编译。 #### 3. 转换工具的选择 - **Mideva**:这是一个早期用于转换 `.m` ...

    邮件库 IMAP/STMP/POP3 Email Library C/C++

    安装包中的程序库包含了实现这些协议的预编译库文件,方便开发者快速集成到项目中。示例代码展示了如何使用这些库函数,对于初学者来说非常有帮助,可以通过模仿示例快速上手。使用手册则提供了详细的API文档和指导...

    JAVA调用C/C++ DLL文件方法

    JAVA 调用 C/C++ 库文件(DLL)是 Java 语言与 C/C++ 语言之间的交互方式之一。在 Java 中,存在多种调用 C/C++ 库文件的方式,包括 JNI、JNative、Jawin 和 Jacob 等。其中,JNI(Java Native Interface)是 Java ...

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++

    CHM是微软的HTML帮助文件格式,包含了C++标准库中的各种类、函数、模板等详细信息,方便开发者查找和学习C++标准库的用法。例如,`std::vector`、`std::string`、`iostream`、`algorithm`等常见模块都在其中有所介绍...

    MATLAB Support for MinGW-w64 C/C++/Fortran Compiler

    - `lib`:存放库文件,用于链接程序。 - `etc`:可能包含配置文件和其他系统相关设置。 - `libexec`:可能包含编译器或链接器的辅助程序。 - `bin`:存放可执行文件,如编译器和链接器本身。 - `opt`:可能包含一些...

    C/C++ API 帮助文档大全(中文,chm格式)

    2. **STL**:Standard Template Library是C++库的一个重要组成部分,提供了模板类实现的容器(如array、deque、set)、迭代器、算法和函数对象。STL的使用大大提高了代码的可读性和复用性。 3. **异常处理**:C++中...

    C /C++库函数及文件大全 经典 chm

    各种函数以及库文件的讲解 可当作编程词典 觉得好再下! &lt;br&gt;General C/C++ Pre-processor commands Operator Precedence Escape Sequences ASCII Chart Data Types Keywords ...

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载 C/C++ 语言参考 基本C/C++ 预处理命令 操作符优先级 转义字符 ASCII码表 基本数据类型 关键字 标准 C 库: Standard C I/O Standard C String...

    MinGW-w64 C/C++编译器+libsvm安装包.rar

    为了使用libsvm,开发者需要将libsvm的头文件(.h)和库文件(.a或.dll)添加到编译路径中,以便编译器能够找到相关函数的定义和实现。 在实际开发中,用户可能还需要了解如何配置Makefile或者项目设置,以便正确...

    Demo: c/c++动态库(DLL)调用,c#等其他语言调用c/c++的DLL

    P/Invoke会处理底层的调用约定和数据类型转换,使得C#能够与C/C++库无缝交互。 5. **示例文件"calldll"**:这个示例可能包含C/C++的DLL源码、C#调用的代码示例以及编译和调用的步骤说明。通常,C/C++ DLL会有一个...

    ActiveMQ C/C++ 编译库需要的文件

    在构建和测试ActiveMQ的C/C++库时,开发者可能会用到这个工具来验证代码的正确性。 2. `apr-1.4.5-win32`: APR(Apache Portable Runtime)是Apache HTTP服务器项目的一部分,提供了一个跨平台的系统接口和库。在...

    C/C++详细函数大全

    C++是C语言的超集,它引入了面向对象编程的概念,因此函数库更为庞大。C++函数大全包含了C语言的所有函数,同时增加了许多C++特有的函数。比如,`new`和`delete`是C++中的内存管理函数,它们与C语言的`malloc`和`...

    详解python如何调用C/C++底层库与互相传值

    Python调用C/C++库,我现在能做到的有两种方式 1.extern “C” 导出(互相传值比较麻烦,不建议使用这种方式): 将C/C++库做成和平常一样的DLL和或者.so,比如: //.h文件 #include //.cpp文件 //C/C++ my.so ...

    PHP调用C/C++生成的.so库的详细笔记

    在IT领域,有时候我们需要利用不同编程语言的优势来完成复杂任务,比如使用PHP处理Web应用程序,同时结合C或C++的高效性能。...通过本文所述的步骤和工具,你可以开始尝试将C/C++库与PHP应用程序无缝结合。

    C/C++头文件包含

    C/C++是平台无关性语言,因此系统相关的process/GUI等不在标准C/C++库中。例如graphics.h和windows.h等是由某个编译器提供的,而不是由C/C++提供的。 语言特点 C/C++只是语言,而且是平台无关性语言。C++是一个多...

Global site tag (gtag.js) - Google Analytics