首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对Android libc++ libc++_shared,libstdc++的混淆

对Android libc++ libc++_shared,libstdc++的混淆
EN

Stack Overflow用户
提问于 2021-11-30 09:04:28
回答 1查看 1.9K关注 0票数 0

我在尝试使用Android 23 (23.1.7779620)构建一个简单的C++库时感到非常困惑。我正在使用CMake,这是一个非常简单的程序:

代码语言:javascript
复制
# CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(mf) 
add_library(mf lib.cpp)

// lib.hpp
#pragma once
#include <string>
std::string foo(std::string);

// lib.cpp
#include "lib.hpp"
std::string foo(std::string str) {
  return std::string{"test"} + str;
}

这是要构建的命令行:

代码语言:javascript
复制
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DANDROID_STL=c++_shared -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29  -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake .. 
cmake --build . -v
  • 第一个问题是,我希望链接到libc++.so,而不是libc++_shared.so。他们之间有什么区别?我读过这篇文章。但是还没有解释libc++libc++_shared之间的区别。
  • 第二个问题甚至是最糟糕的,似乎我正在使用libstdc++!
  • 第三点,我认为clang的c++实现在名称空间std::__1下,但我找不到类似的东西。

我知道使用libc++_shared是因为这个命令:

代码语言:javascript
复制
$ readelf -d libmf.so

Dynamic section at offset 0x76e0 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libm.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc++_shared.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x000000000000000e (SONAME)             Library soname: [libmf.so]

运行nm似乎使用了来自libstdc++的符号

代码语言:javascript
复制
$ nm -gDC libmf.so | grep '__ndk1'
0000000000003af0 T foo(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >)
                 U std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::append(char const*, unsigned long)
$ nm -gDC libmf.so | grep '__1'
$

更新

在这篇文章中解释了libc++.solibc++_shared.so的区别。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-30 10:05:25

通过将-DANDROID_STL=c++_shared传递给CMake调用,您将显式地请求共享运行时,而不是默认运行时。

正如在文献资料中所解释的,规则很简单:

  1. 如果您的所有本机代码都位于一个库中,请使用静态libc++ (默认),这样就可以删除未使用的代码,并拥有尽可能小的应用程序包。
  2. 一旦您包含了额外的库--因为您包含了来自其他地方的预编译库,或者包含了碰巧包含本机代码的Android文件--您就必须切换到共享运行时。

规则的基本原理很简单: C++运行时具有某些全局数据结构,必须初始化一次,并且只能在内存中存在一次。如果您意外地加载了两个库,它们都静态地链接了C++运行时,那么您就有(例如)两个冲突的内存分配器。当您通过其他库分配freedelete内存时,或者如果您跨库边界传递C++ STL对象(如std::string ),这将导致崩溃。

为了完整起见,在较旧的NDK中,libstdc++ ( GNU C++运行时)也包含在NDK中,但NDK r18不再是这种情况。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70166739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档