问一个C++版本混用的问题


#1

现在的需求是,我需要写个c++的动态库给别人用,这个库只暴露纯C的接口

不过呢,他们的程序用gcc4.6 c++03写的,而我这个功能如果能用c++11的话会有很多方便的第三方库来用

但是gcc4.6对c++11支持很差,我需要至少gcc4.8

那么,有什么办法把gcc4.8 c++11写的.so,给他们正常使用呢?我能想到的是-static-libstdc++,把libstdc++静态连接到.so中,不过似乎也有问题


#2

只暴露纯C接口怕啥?


#3
  1. 如何处理-fPIC

  2. 用哪种方法把静态连接的libstdc++符号彻底隐藏

  3. 如果libstdc++内部维护了某些全局资源,程序跑起来后就有两份,是否会引起一些未知问题


#4

你只暴露C接口,关PIC什么事?

GCC 5.1。。。

整个库用匿名namespace试下


#5

我能想到的是-static-libstdc++,把libstdc++静态连接到.so中,不过似乎也有问题

應該用-static-libstdc++。有什麼問題呢?不同版本libstdc++可以混用,兼容問題用version symbol解決了

如何处理-fPIC

不用特別考慮。libstdc++.a本身是-fPIC編譯的。

用哪种方法把静态连接的libstdc++符号彻底隐藏

爲了symbol interposition(executable符號覆蓋DSO中的,第一個鏈接的DSO符號覆蓋其餘DSO的,LD_PRELOAD, …),很多符號在.dynsym中。對於libstdc++,其中多數符號無法隱藏。-shared 鏈接DSO時,以lld爲例,它用ExportDynamic決定符號是否得出現在.dynsym中。除了addShared,多數情況都是無法忽略:

  // lld/tree/master/ELF/SymbolTable.cpp#L224
  if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
    S->ExportDynamic = true;

-fvisibility-inlines-hidden可以隱藏幾個symbols,但對於libstdc++符號作用極小。

如果libstdc++内部维护了某些全局资源,程序跑起来后就有两份,是否会引起一些未知问题

靠symbol interposition。ABI policy https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html 也值得閱讀。 我挺想知道你的應用會因爲多份libstdc++弄出什麼問題,多數是應用程式自身的多版本混用導致的問題。


#6

g++ -static-libstdc++ -Wl,–exclude-libs,libstdc++ -shared -fPIC …


#7

-Wl,–exclude-libs,libstdc++

這樣很危險的,部分符號沒有導出到.dynsym無法interpose:一些__cxa_* , template explicit instantiations(在某個DSO裏inline後可能和其他module用的不相容), …多份typeinfo vtable(typeid可能不準確, exception可能catch不住)…


#8

好吧,我以为只要没有 rdynamic ,那这个DSO应该是自闭的。 有例子能展示你说的 不相容,不准确和exception问题吗?


#9

只导出c接口,肯定不会用exception。另外也不能垮so申请和释放内存,还有两个版本的标准库尽量在同一os里编译,限制很多。

最好做成独立程序,以服务的形式提供api,比如http。