标签: abi

混合使用C++ ABI来构建旧库

在这种情况下,我有一个使用最近的GCC(4.3.3)的C++代码库,但我需要链接一个使用GCC 3.2.3构建的旧库.没有更新版本的库,我不能没有它,它是封闭源,所以它无法重建.

这似乎是一个问题,因为GCC 4.3.3和3.2.3之间存在ABI不兼容性,所以我试图看看我的选择是什么来解决这个问题.

一些额外的细节:

  • 我可以使用-fabi-version = 1在我的代码库中重建所有内容以获得正确的ABI版本,但我依赖于libstdc ++版本6的一些较新功能.
  • 代码库之外的所有C++库依赖项都是开源的,所以我可以根据需要重建它们,除了这个库.
  • 许多C库依赖项无法重建或难以重建.
  • 旧库似乎依赖于某些libstdc ++版本5的功能

我到目前为止尝试过:

  • 使用-fabi-version = 1重建所有C++代码和依赖库,并链接libstdc ++版本6.这会因为C++标准库符号有一些未定义的符号错误而失败.
  • 与上面相同,但另外在libstdc ++ 5的共享库中链接,这解决了链接器问题,但似乎导致在运行时在遗留库内混合两个版本,并导致崩溃.

我阅读了这个页面:http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html这似乎表明可以在应用程序中混合使用C++ ABI版本来满足库之间不同的依赖关系.但是,这似乎并没有很好地工作,除非我遗漏了一些东西.

有任何想法吗?

c++ legacy gcc abi

5
推荐指数
1
解决办法
1181
查看次数

RTTI 跨 Itanium 和 MSVC ABI 中的模块边界

我正在阅读Itanium ABI,上面写着

当且仅当指针相等时,两个 type_info 指针才指向等效类型描述。实现必须满足此约束,例如通过使用符号抢占、COMDAT 部分或其他机制。

有谁知道在流行平台(例如使用 GCC 和 GNU binutils 的 Linux)上使用动态加载库时如何在实践中实现这一点的具体细节?它有多可靠?

另外,我的印象是,typeidMSVC 中的比较是(是?)使用对损坏的符号名称进行运行时字符串比较来实现的,因为不能保证满足此要求。现在还是这样吗?是否存在技术平台限制阻止 MSVC 使用与 Itanium ABI 平台上使用的相同技术?

编辑还有一个问题:跨模块边界(在任一 ABI 中)捕获异常是否也依赖于 RTTI 信息,或者除了运行时的等效机制之外是否还涉及另一种机制dynamic_cast

c++ gcc rtti abi visual-c++

5
推荐指数
1
解决办法
377
查看次数

为 C++ 库创建自动 C 包装器?

假设我有一个 C++ DLL。AFAIK,C++ 没有广泛采用的 ABI 标准,因此为了确保它工作并且不依赖于目标应用程序的编译器,我需要将我的库包装在 C 接口中。

有没有什么工具可以自动生成这样的界面?如果他们可以围绕 C 接口生成包装器,看起来好像它们是原始的 C++ 对象,那也会很好,例如

Foo* f = new Foo();  // FooWrapper* fw = Foo_create();
f->bar("test");      // Foo_bar(fw, "test")
Run Code Online (Sandbox Code Playgroud)

转换为使用生成的 C ABI 在我的库中调用的 C 函数。我知道 C++ 是相当复杂的语言,并不是所有的东西都可以很容易地包装在 C 接口中,但我想知道是否有任何这样的解决方案甚至支持 C++ 语言的一个子集(也许在一些手动编写的 IDL/ XML 文件)?

c c++ abi wrapper

5
推荐指数
1
解决办法
2953
查看次数

IA-64 中的“GP/功能地址对”是什么意思?

安腾 C++ ABI中的“GP/函数地址对”是什么意思?GP代表什么?

itanium abi

5
推荐指数
1
解决办法
644
查看次数

sizeof(struct)如何帮助提供ABI兼容性?

假设C库必须与应用程序代码共享结构的细节,并且必须保持API和ABI向后兼容性.它试图通过检查传递给它的结构的大小来做到这一点.

比如说,需要更新以下结构.在库版本1中,

typedef struct {
    int size;
    char* x;
    int y;
} foo;
Run Code Online (Sandbox Code Playgroud)

在库的第2版中,它更新为:

typedef struct {
    int size;
    char* x;
    int y;
    int z;
} foo_2;
Run Code Online (Sandbox Code Playgroud)

现在,库版本2想要检查应用程序是将新的foo_2还是旧的foo作为参数arg传递给函数.它假定应用程序已设置arg.sizesizeof(foo)sizeof(foo_2)尝试确定应用程序代码是否为版本2.

if(arg.size == sizeof(foo_2)) {
    // The application groks version 2 of the library. So, arg.z is valid. 
} else {
    // The application uses of version 1 of the library. arg.z is not valid.
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么这不会失败.在GCC 4.6.3,与-O3标志,无论是sizeof(foo)sizeof(foo_2) …

c api compatibility abi

5
推荐指数
1
解决办法
726
查看次数

C++ 成员函数的 GCC 别名属性

由于系统标头中的类型更改,我在 Linux 上遇到了可移植性问题。siginfo_t 类型已从命名结构 (struct siginfo) 更改为未命名结构。对我来说,这在 RHEL6 和 RHEL7 之间发生了变化。

我们在一些地方使用了ACE,他们在一些公开的接口中使用了 siginfo_t。结果是在 RHEL7 上编译的代码不会链接到在 RHEL6 上构建的库。暂时,我需要支持这个。

在 RHEL6 中,一个问题函数被输入为:

ACE_Event_Handler::handle_signal(int, siginfo*, ucontext*) 
Run Code Online (Sandbox Code Playgroud)

在 RHEL7 中,它看起来像这样:

ACE_Event_Handler::handle_signal(int, siginfo_t*, ucontext*) 
Run Code Online (Sandbox Code Playgroud)

它们被分解成不同的符号,导致链接期间失败或运行时符号查找失败。

一个相对简单的解决方案是使用函数别名。但是,我不想修改头文件。我有点挣扎,因为这是一个虚拟成员函数。

我尝试在基于 RHEL7 的 ACE 版本上的 Event_Handler.cpp 中执行此操作:

struct siginfo;
ACE_Event_Handler::handle_signal(int, siginfo*, ucontext*)
__attribute__((
  alias("_ZN17ACE_Event_Handler13handle_signalEiP9siginfo_tP8ucontext")
));
Run Code Online (Sandbox Code Playgroud)

有了这个,GCC 抱怨该函数没有被声明。我最终能够完成这项工作,但只有通过这个丑陋的黑客:

extern "C" int _ZN17ACE_Event_Handler13handle_signalEiP7siginfoP8ucontext()
__attribute__((
  alias("_ZN17ACE_Event_Handler13handle_signalEiP9siginfo_tP8ucontext")
));
Run Code Online (Sandbox Code Playgroud)

需要'extern "C"' 以防止重新修改损坏的名称。

有没有更优雅的方法来实现这一点而不会遇到编译器投诉?

c++ alias attributes gcc abi

5
推荐指数
0
解决办法
1602
查看次数

为 C++ 库创建 ac 包装器

是否通过不透明指针将 C++ 库包装到 C 提供了稳定的 ABI 接口?我很清楚 ABI 接口以及为什么 c++ 没有稳定的接口。这与名称修改和许多其他事情有关。我知道 C 在这部分非常稳定。与 C++ 相比,将 C 库包装成各种其他语言也很容易。这两个是为我的库制作 ac API 的驱动力。

将 C++ 库包装为 C 时,底层代码仍然是 C++。我的情况是 C++,带有 boost 共享 ptr 和其他依赖项。

那么既然底层代码是C++,那么ABI的稳定性是如何实现的。或者换句话说,共享库(.so、.dll 等)中仍然编译了 C++ 的东西。

我想知道它是如何工作的。也许有人可以为我提供一个很好地解释这些东西的例子。

c c++ api abi

5
推荐指数
1
解决办法
722
查看次数

发布和调试之间的 ABI 兼容性

使用 GCC 时,考虑到我有时在发布时编译相同的库,有时在调试时编译相同的库,ABI 是否保证兼容?

(同时使用相同的编译器)

我有一个可执行文件和一些共享对象(有些依赖于其他对象),我希望能够交换发布/调试共享对象,而无需重新编译所有内容,而只重新编译感兴趣的共享对象。

这是可能的,还是在某些情况下我可能会以这种方式获得一些未定义的行为?(假设我的代码被严格打包,并在发布和调试中填充)


编辑:

我将详细说明我们看到的问题。我们有一个自定义版本intrusive_ptr,在调试模式下,我们有自己intrusive_ptr一个成员,即 a boost::intrusive_ptr,而在发布中,我们只使用boost::intrusive_ptr. 我们的 APIintrusive_ptr与 相同boost::intrusive_ptr,并且我们在类中没有任何虚函数。
我们看到的是:
如果我们使用所有调试库或所有发布库,则一切正常。如果我们将调试可执行文件与发布库混合使用,则会发生内存泄漏,intrusive_ptr并且不会释放对象。

我们intrusive_ptr和的大小boost::intrusive_ptr在调试和发布中都是相同的(我们的类不会在顶部添加任何大小开销)。

所以我想知道是什么导致了泄漏,ABI 差异是唯一想到的事情。

想法?

c++ gcc compilation abi shared-ptr

5
推荐指数
1
解决办法
776
查看次数

为什么裸 Rust 函数中有额外的 ASM 指令?

我在 Rust 中包装了一个低级别的 ABI,利用了naked函数特性。这是我的代码和相关的反汇编

#![feature(asm)]
#![feature(naked_functions)]

struct MyStruct {
    someVar: i64, // not important
                  // ...
}

impl MyStruct {
    #[naked]
    extern "C" fn wrap(&self) {
        unsafe {
            asm!("NOP" :::: "volatile");
            // not sure if the volatile option is needed, but I
            // figured it wouldn't hurt
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用LLDB反汇编:

ABIWrap`ABIWrap::{{impl}}::wrap:
  * 0x100001310 <+0>:  movq   %rdi, -0x10(%rbp)
  * 0x100001314 <+4>:  movq   %rsi, -0x8(%rbp)
  * 0x100001318 <+8>:  movq   -0x10(%rbp), %rax
  * 0x10000131c <+12>: movq   -0x8(%rbp), %rcx
  * 0x100001320 …
Run Code Online (Sandbox Code Playgroud)

x86 abi wrapper rust

5
推荐指数
1
解决办法
1114
查看次数

C++ ABI如何处理RVO和NRVO?

我很困惑与问候如何编译和链接处理的事实,在电话会议上要求ER功能的依靠,如果函数使用静脉阻塞或NRVO不同.

这可能是我的误解,但我的假设是通常没有RVO或NRVO

std::string s = get_string();
Run Code Online (Sandbox Code Playgroud)

如果get_string不执行N?RVO但是如果get_string执行N?RVO调用代码什么也不做,并且s由函数get_string构造到位,则涉及从get_string的结果移动构造s .

编辑:这是我如何设想get_string调用程序操作,如果没有N?RVO:

  1. 调用get_string()
  2. get_string结果现在在堆栈上,调用者使用它来构造s

现在还有RVO

  1. 调用get_string()
  2. 当get_string完成时,堆栈上没有结果,get_string构造为s,调用者不需要做任何事情来构造s.

c++ abi rvo nrvo

5
推荐指数
1
解决办法
394
查看次数

标签 统计

abi ×10

c++ ×7

gcc ×4

c ×3

api ×2

wrapper ×2

alias ×1

attributes ×1

compatibility ×1

compilation ×1

itanium ×1

legacy ×1

nrvo ×1

rtti ×1

rust ×1

rvo ×1

shared-ptr ×1

visual-c++ ×1

x86 ×1