什么是应用程序二进制接口 (ABI)? [英] What is an application binary interface (ABI)?

查看:30
本文介绍了什么是应用程序二进制接口 (ABI)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从来没有清楚地理解 ABI 是什么.请不要将我指向维基百科的文章.如果我能理解,我就不会在这里发这么长的帖子了.

I never clearly understood what an ABI is. Please don't point me to a Wikipedia article. If I could understand it, I wouldn't be here posting such a lengthy post.

这是我对不同界面的看法:

This is my mindset about different interfaces:

电视遥控器是用户与电视之间的接口.它是一个现有的实体,但本身无用(不提供任何功能).遥控器上每个按钮的所有功能都在电视机中实现.

A TV remote is an interface between the user and the TV. It is an existing entity, but useless (doesn't provide any functionality) by itself. All the functionality for each of those buttons on the remote is implemented in the television set.

接口:它是一个现有实体"层.该功能的 functionalityconsumer.一个接口本身不做任何事情.它只是调用背后的功能.

Interface: It is an "existing entity" layer between the functionality and consumer of that functionality. An interface by itself doesn't do anything. It just invokes the functionality lying behind.

现在根据用户的不同,有不同类型的界面.

Now depending on who the user is there are different type of interfaces.

命令行界面 (CLI) 命令是现有实体,消费者就是用户,功能在后面.

Command Line Interface (CLI) commands are the existing entities, the consumer is the user and functionality lies behind.

functionality: 我的软件功能解决了一些问题我们描述这个接口的目的.

functionality: my software functionality which solves some purpose to which we are describing this interface.

现有实体: 命令

消费者:用户

图形用户界面(GUI)窗口、按钮等是现有的实体,同样,消费者是用户,功能在后面.

Graphical User Interface(GUI) window, buttons, etc. are the existing entities, and again the consumer is the user and functionality lies behind.

功能:我的软件功能,它解决了我们描述这个接口的一些问题.

functionality: my software functionality which solves some problem to which we are describing this interface.

现有实体: 窗口、按钮等.

消费者:用户

应用程序编程接口(API) 函数(或将更正确)接口(在基于接口的编程中)是现有实体,这里的消费者是另一个程序而不是用户,再次功能位于这一层之后.

Application Programming Interface(API) functions (or to be more correct) interfaces (in interfaced based programming) are the existing entities, consumer here is another program not a user, and again functionality lies behind this layer.

functionality: 我的软件功能解决了一些问题我们正在描述这个接口的问题.

functionality: my software functionality which solves some problem to which we are describing this interface.

现有实体: 函数、接口(函数数组).

existing entities: functions, Interfaces (array of functions).

消费者:另一个程序/应用程序.

consumer: another program/application.

应用程序二进制接口 (ABI) 这是我的问题开始的地方.

Application Binary Interface (ABI) Here is where my problem starts.

功能: ???

现有实体: ???

消费者: ???

  • 我用不同的语言编写过软件并提供了不同类型的接口(CLI、GUI 和 API),但我不确定我是否提供过任何 ABI.
  • 维基百科说:

    ABI 涵盖详细信息,例如

    ABIs cover details such as

    • 数据类型、大小和对齐方式;
    • 调用约定,控制函数的参数如何传递和返回值检索;
    • 系统调用号以及应用程序应如何进行系统调用到操作系统;

    其他 ABI 标准化细节,例如

    Other ABIs standardize details such as

    • C++ 名称修改,
    • 异常传播,以及
    • 同一平台上编译器之间的调用约定,但不需要跨平台兼容性.

    • 谁需要这些详细信息?请不要说操作系统.我知道汇编编程.我知道如何链接 &加载工程.我确切地知道里面发生了什么.

      • Who needs these details? Please don't say the OS. I know assembly programming. I know how linking & loading works. I know exactly what happens inside.

        为什么会出现 C++ 名称修改?我以为我们在二进制级别上讨论.为什么会出现语言?

        Why did C++ name mangling come in? I thought we are talking at the binary level. Why do languages come in?

        无论如何,我已经下载了 [PDF] System V Application Binary Interface 4.1 版 (1997-03-18) 看看它到底包含什么.好吧,大部分都没有任何意义.

        Anyway, I've downloaded the [PDF] System V Application Binary Interface Edition 4.1 (1997-03-18) to see what exactly it contains. Well, most of it didn't make any sense.

        • 为什么它包含两章(第 4 章和第 5 章)来描述 ELF 文件格式?事实上,这是该规范仅有的两个重要章节.其余章节是特定于处理器的".无论如何,我认为这是一个完全不同的话题.请不要说 ELF 文件格式规范 ABI.根据定义,它不符合成为接口的条件.

        • Why does it contain two chapters (4th & 5th) to describe the ELF file format? In fact, these are the only two significant chapters of that specification. The rest of the chapters are "processor specific". Anyway, I though that it is a completely different topic. Please don't say that ELF file format specifications are the ABI. It doesn't qualify to be an interface according to the definition.

        我知道,既然我们在这么低的层面上谈论它,它必须非常具体.但我不确定它是如何特定于指令集架构 (ISA)"的?

        I know, since we are talking at such a low level it must be very specific. But I'm not sure how is it "instruction set architecture (ISA)" specific?

        在哪里可以找到 Microsoft Windows 的 ABI?

        Where can I find Microsoft Windows' ABI?

        所以,这些是困扰我的主要问题.

        So, these are the major queries that are bugging me.

        推荐答案

        理解ABI"的一个简单方法是将其与API"进行比较.

        One easy way to understand "ABI" is to compare it to "API".

        您已经熟悉 API 的概念.如果您想使用某个库或您的操作系统的功能,您将针对 API 进行编程.API 由数据类型/结构、常量、函数等组成,您可以在代码中使用这些数据类型/结构来访问该外部组件的功能.

        You are already familiar with the concept of an API. If you want to use the features of, say, some library or your OS, you will program against an API. The API consists of data types/structures, constants, functions, etc that you can use in your code to access the functionality of that external component.

        ABI 非常相似.将其视为 API 的编译版本(或机器语言级别的 API).编写源代码时,您可以通过 API 访问库.编译代码后,您的应用程序将通过 ABI 访问库中的二进制数据.ABI 定义了编译后的应用程序将用于访问外部库的结构和方法(就像 API 所做的那样),只是在较低级别上.您的 API 定义了将参数传递给函数的顺序.您的 ABI 定义了如何传递这些参数的机制(寄存器、堆栈等).您的 API 定义了哪些函数是您的库的一部分.您的 ABI 定义了您的代码如何存储在库文件中,以便任何使用您的库的程序都可以找到所需的函数并执行它.

        An ABI is very similar. Think of it as the compiled version of an API (or as an API on the machine-language level). When you write source code, you access the library through an API. Once the code is compiled, your application accesses the binary data in the library through the ABI. The ABI defines the structures and methods that your compiled application will use to access the external library (just like the API did), only on a lower level. Your API defines the order in which you pass arguments to a function. Your ABI defines the mechanics of how these arguments are passed (registers, stack, etc.). Your API defines which functions are part of your library. Your ABI defines how your code is stored inside the library file, so that any program using your library can locate the desired function and execute it.

        对于使用外部库的应用程序,ABI 很重要.库中充满了代码和其他资源,但您的程序必须知道如何在库文件中找到它需要的内容.您的 ABI 定义了库的内容如何存储在文件中,您的程序使用 ABI 搜索文件并找到它需要的内容.如果您系统中的所有内容都符合相同的 ABI,那么任何程序都可以使用任何库文件,无论它们是谁创建的.Linux 和 Windows 使用不同的 ABI,因此 Windows 程序不知道如何访问为 Linux 编译的库.

        ABIs are important when it comes to applications that use external libraries. Libraries are full of code and other resources, but your program has to know how to locate what it needs inside the library file. Your ABI defines how the contents of a library are stored inside the file, and your program uses the ABI to search through the file and find what it needs. If everything in your system conforms to the same ABI, then any program is able to work with any library file, no matter who created them. Linux and Windows use different ABIs, so a Windows program won't know how to access a library compiled for Linux.

        有时,ABI 更改是不可避免的.发生这种情况时,除非重新编译以使用新版本的库,否则使用该库的任何程序都将无法运行.如果 ABI 更改但 API 没有更改,则新旧库版本有时称为源兼容".这意味着虽然为一个库版本编译的程序不能与另一个库版本一起使用,但为一个库版本编写的源代码在重新编译后将适用于另一个库版本.

        Sometimes, ABI changes are unavoidable. When this happens, any programs that use that library will not work unless they are re-compiled to use the new version of the library. If the ABI changes but the API does not, then the old and new library versions are sometimes called "source compatible". This implies that while a program compiled for one library version will not work with the other, source code written for one will work for the other if re-compiled.

        因此,开发人员倾向于尝试保持其 ABI 稳定(以尽量减少中断).保持 ABI 稳定意味着不更改函数接口(返回类型和数量、类型和参数顺序)、数据类型或数据结构的定义、定义的常量等.可以添加新的函数和数据类型,但必须保留现有的函数和数据类型相同.例如,如果您的库使用 32 位整数来指示函数的偏移量并且您切换到 64 位整数,那么使用该库的已编译代码将无法正确访问该字段(或任何跟随它的字段).访问数据结构成员会在编译期间转换为内存地址和偏移量,如果数据结构发生变化,那么这些偏移量将不会指向代码期望它们指向的内容,并且结果充其量是不可预测的.

        For this reason, developers tend to try to keep their ABI stable (to minimize disruption). Keeping an ABI stable means not changing function interfaces (return type and number, types, and order of arguments), definitions of data types or data structures, defined constants, etc. New functions and data types can be added, but existing ones must stay the same. If, for instance, your library uses 32-bit integers to indicate the offset of a function and you switch to 64-bit integers, then already-compiled code that uses that library will not be accessing that field (or any following it) correctly. Accessing data structure members gets converted into memory addresses and offsets during compilation and if the data structure changes, then these offsets will not point to what the code is expecting them to point to and the results are unpredictable at best.

        ABI 不一定是您要明确提供的东西,除非您从事的是非常底层的系统设计工作.它也不是特定于语言的,因为(例如)C 应用程序和 Pascal 应用程序在编译后可以使用相同的 ABI.

        An ABI isn't necessarily something you will explicitly provide unless you are doing very low-level systems design work. It isn't language-specific either, since (for example) a C application and a Pascal application can use the same ABI after they are compiled.

        关于您对 SysV ABI 文档中有关 ELF 文件格式的章节的问题:包含此信息的原因是因为 ELF 格式定义了操作系统和应用程序之间的接口.当您告诉操作系统运行程序时,它希望程序以某种方式格式化,并且(例如)希望二进制文件的第一部分是一个 ELF 标头,其中包含特定内存偏移处的某些信息.这就是应用程序如何将有关自身的重要信息传达给操作系统的方式.如果您以非 ELF 二进制格式(例如 a.out 或 PE)构建程序,则需要 ELF 格式应用程序的操作系统将无法解释二进制文件或运行应用程序.这是 Windows 应用程序无法直接在 Linux 机器上运行(反之亦然)的一个重要原因,而无需重新编译或在某种可以从一种二进制格式转换为另一种格式的仿真层中运行.

        Regarding your question about the chapters regarding the ELF file format in the SysV ABI docs: The reason this information is included is because the ELF format defines the interface between operating system and application. When you tell the OS to run a program, it expects the program to be formatted in a certain way and (for example) expects the first section of the binary to be an ELF header containing certain information at specific memory offsets. This is how the application communicates important information about itself to the operating system. If you build a program in a non-ELF binary format (such as a.out or PE), then an OS that expects ELF-formatted applications will not be able to interpret the binary file or run the application. This is one big reason why Windows apps cannot be run directly on a Linux machine (or vice versa) without being either re-compiled or run inside some type of emulation layer that can translate from one binary format to another.

        IIRC,Windows 当前使用 Portable Executable(或 PE)格式.该维基百科页面的外部链接"部分中有链接,其中包含有关 PE 格式的更多信息.

        IIRC, Windows currently uses the Portable Executable (or, PE) format. There are links in the "external links" section of that Wikipedia page with more information about the PE format.

        另外,关于您关于 C++ 名称修改的注释:在库文件中定位函数时,通常按名称查找该函数.C++ 允许您重载函数名称,因此仅名称不足以识别函数.C++ 编译器有自己的内部处理方式,称为name mangling.ABI 可以定义对函数名称进行编码的标准方式,以便使用不同语言或编译器构建的程序可以找到所需的内容.当您使用 extern "c" 在 C++ 程序中,您指示编译器使用标准化的方式来记录其他软件可以理解的名称.

        Also, regarding your note about C++ name mangling: When locating a function in a library file, the function is typically looked up by name. C++ allows you to overload function names, so name alone is not sufficient to identify a function. C++ compilers have their own ways of dealing with this internally, called name mangling. An ABI can define a standard way of encoding the name of a function so that programs built with a different language or compiler can locate what they need. When you use extern "c" in a C++ program, you're instructing the compiler to use a standardized way of recording names that's understandable by other software.

        这篇关于什么是应用程序二进制接口 (ABI)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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