标签: abi

C#接口破坏,ABI

假设我们class X在程序集的版本1中A.dll:

class X {
    SomeType Property { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

然后在程序集的第2版中A.dll:

class X {
    SomeType Property { set; get; }
    SomeType OtherProperty { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们有第二个B.dll加载A.dll和使用X的程序集.是否会添加属性会OtherProperty破坏ABI?将B.dll无法使用A.dll/ X?如果没有,声明的顺序会有什么不同吗?如果属性是虚拟的,它有什么不同吗?

我想我真的在问:ABI的一般规则是什么?我知道在发布之后更改接口是一件坏事,但我真的希望能够在某些情况下添加属性,而无需添加子类.

.net c# abi binary-compatibility

9
推荐指数
2
解决办法
1830
查看次数

Objective-C 2.0 ABI规范

Objective-C 2.0 ABI的文档是否存在于Internet上的某个位置?该发行说明objc4-493.9说:

即将出版的文档将仅描述使用编译器和开发人员工具的ABI.

它已经发布了吗?最接近的此类引用是Apple的Objective-C运行时引用,但这仅描述面向公众的API而不是实现细节.事实上,它甚至提到了ABI:

此外,新的Objective-C ABI(此处未描述)[...]

不幸的是,新的ABI在上述文本中没有超链接.:-)是我唯一的选择,以了解objc4运行时和Clang的CGObjCNonFragileABIMac代码生成项目的源代码?

objective-c abi language-specifications

9
推荐指数
1
解决办法
1079
查看次数

如何避免二进制文件中的STT_GNU_IFUNC符号?

我需要部署到Red Hat 4.1.2框(具有gcc 4.1.2).我在Ubuntu 11.10上使用GCC 4.6.1进行开发.不幸的是,我的构建过程创建的一些二进制文件在RedHat机器上不可用.原因似乎是ABI更改,根据另一个Stackoverflow问题导致STT_GNU_IFUNC符号的引入.有没有办法阻止导出任何这样的符号,以便我的二进制文件可以使用旧的ABI?我使用nm在我的二进制文件中查找"i"类型的任何符号,但没有找到.

我问这个,因为我的一些其他的二进制文件,以及一些第三方库我建(TBB,升压),不使用新的ABI等运行RedHat的机器上的罚款.

希望很清楚.提前致谢.

linux gcc abi

9
推荐指数
1
解决办法
1万
查看次数

检测与GCC的ABI兼容性问题

我最近花了相当多的时间来追踪一个问题,原因是编译了一个库-D_GLIBCXX_DEBUG(告诉libstdc ++使用带有额外检查的标准库的调试版本),但没有编译客户端程序.这导致了ABI兼容性问题.

有什么方法可以通过GCC自动检测这样的问题吗?Visual Studio提供了我认为可以用于此目的的detect_mismatch编译指示,但我不知道任何GCC等价物.GCC通过嵌入符号名称(例如GLIBCXX_3.4.9)做了一些事情,我可以想象如果相应的符号(例如mylib_debug_stl)不存在则会因为未定义的符号而导致链接错误的方案,但是我能想到的唯一方法是使用那个符号真是太烂了.

或者,其他人如何避免这个问题?将库的已检查版本构建为不同的名称或类似的名称?

debugging gcc glibc g++ abi

9
推荐指数
1
解决办法
789
查看次数

Visual Studio参数对齐限制和Windows x64 ABI

使用WIN32上的Visual C++,具有4个或更多SSE参数的函数存在长期存在的问题,例如

__m128i foo4(__m128i m0, __m128i m1, __m128i m2, __m128i m3) {}
Run Code Online (Sandbox Code Playgroud)

生成错误:

align.c(8) : error C2719: 'm3': formal parameter with __declspec(align('16')) won't be aligned
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,即使函数是,Visual C++仍然会不必要地强加ABI限制__inline.

我想知道这是否仍然是64位Windows上的问题?ABI限制是否仍适用于x64?

(我无法访问64位Windows系统,否则我会亲自尝试,并且广泛的Google搜索没有发现任何确定的内容.)

windows 64-bit sse abi visual-c++

9
推荐指数
1
解决办法
933
查看次数

为什么Clang强制结构参数为整数

在函数中使用struct参数时,clang将更改函数签名.签名将是一个相同大小的强制int,而不是使用结构类型.在我的编译器项目中,我使用llvm结构类型作为方法签名(这似乎更合乎逻辑).

这不会是一个问题,除了LLVM在使用struct或coerced类型时产生的汇编是不同的而不是调用兼容的事实.这导致我的编译器不与具有结构的C函数ABI兼容.

为什么clang这样做?这是C ABI中指定的内容吗?

这是一个简单的示例C源文件:

struct TwoInt { int a, b; };

struct EightChar { char a, b, c, d, e, f, g, h; };

void doTwoInt(struct TwoInt a) {}

void doEightChar(struct EightChar a) {}

int main()
{
        struct TwoInt ti;
        struct EightChar fc;

        doTwoInt(ti);
        doEightChar(fc);

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

从Clang得到的LLVM-IR

%struct.TwoInt = type { i32, i32 }
%struct.EightChar = type { i8, i8, i8, i8, i8, i8, i8, i8 }

define void @doTwoInt(i64 %a.coerce) nounwind uwtable {
  %a …
Run Code Online (Sandbox Code Playgroud)

compiler-construction struct abi llvm clang

9
推荐指数
1
解决办法
1751
查看次数

为什么应用程序二进制接口对编程很重要

我不明白为什么ABI是开发用户空间应用程序的重要环境.是否将操作系统的系统调用集视为ABI?但是,如果是这样,那么关于标准库中封装的系统调用的所有复杂性是不是都很复杂?

那么ABI兼容性仅与在不同平台上运行静态链接应用程序相关,因为系统调用将嵌入到二进制文件中?

c c++ operating-system abi binary-compatibility

8
推荐指数
2
解决办法
1604
查看次数

为什么libcxx应用__forceinline或GCC等效于其已隐藏的内联函数?

我想明白为什么内联函数的libc ++可见性宏使用__forceinline__attribute__((__always_inline__))作为与内联函数关联的属性的一部分.

有关背景,请参阅

如果这些内联函数将被标记为__visibility__("hidden")无论如何,为什么还需要强制编译器内联它们?

我已经考虑了一下,我有一些假设,但似乎没有一个对我完全满意:

  • 这是为了确保符号不会意外地成为ABI的一部分.如果在构建库时,编译器选择不内联函数,它可能会成为外部符号,因此成为ABI的一部分.但这个hidden属性不足够吗?同样,在构建库时是否只需要强制内联函数?消费者不应该在意.
  • 这是为了确保函数永远不会有定义,以避免ODR问题,编译器选择不在库本身中内联函数,并选择不在函数中嵌入由库的客户端生成的代码,产生两种不同的定义.但这不是预期(和接受)使用的结果visibility("hidden")吗?
  • 它是libc ++设计中特定的东西,作为标准库的实现.

我问这个是因为我正在构建一个C++库,我希望有一天能够标准化ABI,我正在使用libc ++作为指导.到目前为止,它运作良好,但这个问题引起了一些人头疼.

特别是,我们有报道称用户抱怨MSVC拒绝遵守该__forceinline属性,从而导致警告.我们提出的解决方案是__forceinline在构建库时将模拟扩展到INLINE_VISIBILITY仅包括(或GCC等效),假设上面的第一个解释.

但是,由于我们并不完全相信我们理解强制内联函数背后的原因,__forceinline或者__attribute__((__always_inline__))首先,我们对采用这种解决方案有点犹豫不决.

任何人都可以提供一个明确的答案,为什么libc ++需要强制内联其内联函数,即使它们已被装饰为具有隐藏的可见性?

c++ dll shared-libraries abi libc++

8
推荐指数
1
解决办法
305
查看次数

是什么决定了Linux上共享库的二进制兼容性?

我正在Linux上构建一个共享库,它作为某些软件的"插件"(具体来说,它扩展了Mathematica).

我发现如果我构建在Ubuntu 16.04上,生成的库在RHEL 7.6上不起作用.但是,如果我在RHEL 7.6上构建,那么该库可以在RHEL和Ubuntu上运行.

通过"不工作",我指的是数学拒绝加载它,但它只是给出了一个通用的,无用的"加载失败"错误消息.

我已经消除了许多可能破坏兼容性的因素,我找不到了.这个问题是关于其他可能影响兼容性的问题,而不是我在下面列出

该库是用C和C++混合编写的,但它导出了一个C接口.它是用-static-libstdc++和建造的-static-libgcc.如果我ldd.so文件上使用它,它列出的唯一依赖项是:

linux-vdso.so.1 =>  (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
Run Code Online (Sandbox Code Playgroud)

不兼容的一个潜在来源是glibc版本.我查看了库中的符号,nm -gC我在Ubuntu上构建的最高GLIBC版本参考是2.14.RHEL 7.6有glibc 2.17,比2.14更新.因此,我不认为不相容是由于glibc.

还有什么可以导致在Ubuntu 16.04上编译的共享对象不能在RHEL 7.6上加载?


更新:我设法哄Mathematica给出一个更具描述性的错误(这是一个记录不完整的功能),所以我有一个具体的错误信息.在@ Ctx提出的建议中也可以看到同样的情况LD_DEBUG=all.

错误是:

IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
Run Code Online (Sandbox Code Playgroud)

(IGraphM.so是我的图书馆.)

除非我弄错了,否则这个函数似乎是libstdc ++的一部分.如果我指定-static-libstdc++并验证了ldd没有列出libstdc ++ ,为什么会出现此错误?


更新2:

根据SergeyA和本QA的建议,我在定义后编译_GLIBCXX_USE_CXX11_ABI=0. 这确实解决了不兼容问题.

但我仍然不明白为什么.错误消息抱怨缺少符号.这个符号通常从哪里加载?我的印象是,如果我使用-static-libstdc++,那么它应该包含在我的库中.这似乎是错误的.

虽然我似乎有一个实用的解决方案来解决这个特定情况的不兼容性,但我会感谢一些解释,所以将来我可以自己解决类似的问题.

c c++ linux shared-libraries abi

8
推荐指数
1
解决办法
453
查看次数

长长在 c99

在 C99 标准中,他们引入了long long. 这样做的目的是什么?在我(有限的)C 编程经验中,我只见过 4 字节的 int 和 8 字节的 long。例如,从编译器资源管理器: 在此处输入图片说明

如果long已经是8,为什么还需要添加另一种long long类型?这对编译器/架构有什么影响?

c assembly types abi long-long

8
推荐指数
1
解决办法
333
查看次数