与_GLIBCXX_USE_CXX11_ABI=0的std::功能GCC-4是不同的GCC-5和折叠版本。
以下代码向您展示了这一事实:
==> lib.cc <==
#include <functional>
std::function<int(const void*p)> holder;
int run_holder(const void *p)
{
return holder(p);
}==> main.cc <==
#include <stdio.h>
#include <functional>
extern int run_holder(const void*p);
extern std::function<int(const void*p)> holder;
int foo(const void* p)
{
printf("p=%p\n", p);
return 0;
}
int main()
{
holder = foo;
foo((void*)0x12345678);
holder((void*)0x12345678);
run_holder((void*)0x12345678);
}==> make.sh <==
#!/bin/bash
GCC4=/usr/bin/g++
GCCN="scl enable devtoolset-5 -- g++"
$GCC4 -std=c++11 -c -g lib.cc -shared -o libfoo.so &&
$GCCN -std=c++11 -L. -lfoo -g main.cc -o a.out &&
LD_LIBRARY_PATH=. ./a.out预期结果如下:
p=0x12345678
p=0x12345678
p=0x12345678实际结果:
p=0x12345678
./make.sh: line 6: 973 Segmentation fault LD_LIBRARY_PATH=. ./a.out原因是没有文档的std::function的实现。
gcc4: /usr/include/c++/4.8.2/Functional2430
typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);gcc5: /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/functional:2226 gcc8: /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/std_function.h:609
using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);因此,我不能用.so编写gcc4编译的、由gcc5 5/6/7/8编译的函数。没有像_GLIBCXX_USE_CXX11_ABI这样的宏可以控制行为。
发布于 2020-02-24 10:54:27
,所以我不能使用std::函数编写.so,它由gcc4编译,由gcc5/6/7/8使用。
对,是这样。无论是红帽还是GCC项目都没有宣称这是可能的,恰恰相反。GCC 4.x中的C++11支持是不完整和不稳定的,受ABI变化和API变化的影响。你想做的事从来没有得到支持。
我已经在https://stackoverflow.com/a/49119902/981959上更详细地解释了这一点
开发人员工具集文档也涵盖了它(重点是我):
“C++11或C++14模式下的编译器只有在来自同一版本系列(例如6.x)的C++11或C++14模式下才能与另一个编译器兼容。
..。
“红帽开发人员工具集支持使用C++14语言版本,当使用相应标志编译的所有C++对象都已使用6或更高版本生成时。系统GCC在默认模式C++98中编译的对象也是兼容的,但是用C++11或C++14模式编译的系统GCC编译的对象不兼容。__。”
没有像_GLIBCXX_USE_CXX11_ABI这样的宏可以控制行为。
我们不提供宏来控制不受支持和无法工作的东西。
如果您想使用C++11和GCC版本的混合版本,您需要使用一个对C++11具有稳定的、非实验性支持的版本,而不是GCC 4.x。
https://stackoverflow.com/questions/60291845
复制相似问题