如何从共享库调用函数? [英] How does calling a function from a shared library work?

查看:50
本文介绍了如何从共享库调用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在运行时之前加载共享库并将其提供的符号(即函数)添加到全局偏移表中.

When you load a shared library right before runtime, and add the symbols (i.e. functions) it provides to a global offset table.

调用该函数提供的功能时会发生什么?因为您已经编译了代码,所以该功能必须已经指向某个地方.

What happens when you call a function it provides? Because you already compiled your code, so the function had to point somewhere already.

推荐答案

假设您有一个包含以下文件的项目 hello :

Let's assume you have a project hello with the following files:

  • main.cpp
  • function.cpp
  • class.cpp

现在您要使用 g ++ 构建项目.构建过程将如下所示:

Now you want to build the project with g++. The build process will go like this:

----------------      -------      --------------        -------------
| function.cpp | ---> | g++ | ---> | function.o |        | libstdc++ |
----------------      -------      --------------        -------------
                                                 \      /
------------          -------      ----------     ------      ---------
| main.cpp | -------> | g++ | ---> | main.o | --> | ld | ---> | hello |
------------          -------      ----------     ------      ---------
                                                 /
-------------         -------      -----------  /
| class.cpp | ------> | g++ | ---> | class.o | /
-------------         -------      -----------

这里的g++是编译器,它把你的源文件一一编译成目标文件.它只是检查语法错误,未定义的函数或变量.尽管 cpp (C预处理程序)是在编译器之前执行的,但这是另一个主题.编译完所有源文件后,作为链接程序的 ld 将目标文件链接到一个可执行文件中.现在,假设 main.cpp 调用一个名为 hello-function 的函数,该函数在 function.cpp 中实现,并使用 std ::cout ,定义为 libstdc ++ (C ++标准库).编译器将 main.cpp 编译为目标文件,因为该代码有效.当所有目标文件都通过链接器时,它将读取这些对象并找到所引用的函数和变量.如果不将 function.o (包含 hello-function 实现)传递给链接器,则会收到一条错误消息,提示 undefined reference .现在,让我们假设 main.cpp 调用一个在外部库中可用的函数.如果您没有为链接程序指定库,它将显示 undefined reference .如果没有错误,链接器会将所有目标文件链接到一个可执行文件中,并提供有关生成的可执行文件所依赖的共享库的信息.

Here g++ is the compiler which compiles your source files into an object file one by one. It just checks for syntax errors, undefined functions or variables. Although cpp (C Preprocessor) is executed before compiler, that's another topic. After all of your source files are compiled, ld , which is the linker, links your object files into one executable. Now, let's say main.cpp calls a function named hello-function , implemented in function.cpp , and uses std::cout, defined libstdc++ (C++ Standard Library). Compiler compiles main.cpp into object file as the code is valid. When all the of object file passed the linker, it will read those objects and finds the functions and variable that are referred. If you don't pass function.o (which contains hello-function implementation) to the linker, you will get an error saying undefined reference . Now, let's assume that main.cpp calls a function which available in an external library. If you don't specify the library to the linker, it will show you undefined reference . When there is no error, linker links all object file into an executable and puts informantion about the shared libraries on which the resulting executable depends.

在编译并链接程序之后,您可以执行该程序.当您执行它时,您的操作系统(在本例中为Linux)将可执行文件加载到内存中.之后,它将读取文件并确定所需的库,如果尚未加载它们,则将其加载.然后,它执行程序,并且每当找到对外部库的引用时,它将引用转换为实际的内存位置并调用它.程序完成执行后,您的操作系统将释放未使用的内存并卸载所有未使用的库.

After your program is compiled and linked, you can execute the program. When you execute it, your operating system (in this case it's Linux) loads the executable into memory. After that, it reads the file and determine which libraries it requires and loads them if they aren't already loaded. Then it executes the program, and whenever it finds a reference to an external library, it translates the reference to actual memory location and calls it. After the program finishs execution, your operating system frees unused memories and unloads any unused libraries.

此外,如果您的程序链接到一个共享库,而该共享库的版本与在链接阶段所链接的程序的版本不同,则可能会出现"分段错误".

Also, if your program links with a shared library whose version is different than the version your program linked against during linking stage, you might get a "segmentation fault".

这篇关于如何从共享库调用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆