Android NDK需要gnustl_static std::string而不是std::_ndk1::string

Android NDK需要gnustl_static std::string而不是std::_ndk1::string,android,c++,android-ndk,Android,C++,Android Ndk,我正在挂接一个使用gnustl std::string而不是libc++std::\u ndk1::string编译的现有库。如果我试图设置或访问这些字符串,我只会得到垃圾。在hook应用程序中,如何将std::string转换为std:\ndk1::string,反之亦然 我无法使用-DANDROID\u STL=gnustl\u shared编译我的钩子,因为它已不存在,其他正在使用的库需要libc++ 文档中提到了这一点,因为各种STL彼此不兼容。例如,libc++中std::string

我正在挂接一个使用gnustl std::string而不是libc++std::\u ndk1::string编译的现有库。如果我试图设置或访问这些字符串,我只会得到垃圾。在hook应用程序中,如何将std::string转换为std:\ndk1::string,反之亦然

我无法使用-DANDROID\u STL=gnustl\u shared编译我的钩子,因为它已不存在,其他正在使用的库需要libc++

文档中提到了这一点,因为各种STL彼此不兼容。例如,libc++中std::string的布局与gnustl中的布局不同,这正是问题所在。

要使用gnustl,可以使用或更早版本编译所有本机代码。这是一条危险的道路,因为许多重要的bug,包括与安全相关的bug,从那时起就被修复了

另一种不受支持且不推荐的解决问题的方法是从NDKR.17获取gnustl源代码,并用最新的NDK版本编译它们

您最好的选择是使用最新版本的NDK及其c++\U共享运行库重新构建所有依赖项。

要使用gnustl,您可以使用或更早版本编译所有本机代码。这是一条危险的道路,因为许多重要的bug,包括与安全相关的bug,从那时起就被修复了

另一种不受支持且不推荐的解决问题的方法是从NDKR.17获取gnustl源代码,并用最新的NDK版本编译它们


您最好的选择是使用最新版本的NDK及其c++\U共享运行时库重建所有依赖项。

以下是我目前提出的建议,非常不理想:

StringsProxy.cc

包括StringsProxy.h 包括 包括 使用名称空间std; __属性\可视性默认值 外部C StringsProxy::StringsProxyconst char*内容 { set_string=std::stringcontents; } __属性\可视性默认值 外部C StringsProxy::StringsProxy{ 设置字符串=*重新解释字符串; } __属性\可视性默认值 外部C常量char*StringsProxy::C_str{ 返回set_string.c_str; } __属性\可视性默认值 外部C常量uintptr_t*StringsProxy::ptr{ 返回reinterpret\u cast和set\u字符串; } __属性\可视性默认值 外部C StringsProxy::~StringsProxy{ } StringsProxy.h

ifndef\uuuu STRINGSPROXY\uH__ 定义字符串Proxy__ 包括 typedef std::基本字符串代理字符串; StringsProxy类 { 公众: /*使用指向现有字符串的指针初始化StringsProxy*/ StringsProxyuintptr_t str; /*使用新字符串初始化StringsProxy*/ StringsProxyconst char*str; /*获取C字符串*/ 虚拟常量字符*c_str; /*获取要注入的字符串的指针*/ const-virtual-uintpttr_*ptr; 私人: 代理字符串集合字符串; }; 恩迪夫 使用带有-DCMAKE\u ANDROID\u STL\u TYPE=gnustl\u static的旧NDK将其编译为共享对象

然后将此共享对象链接到CmakeList中的挂钩程序: 目标链接库${target\u NAME}${CMAKE\u CURRENT\u SOURCE\u DIR}/abiproxy/build/armeabi-v7a/libabiproxy.so

然后在挂钩程序中,可以这样使用:

包括abiproxy/StringsProxy.h void*seturidebuguintpttr\u t a1,uintptpr\u t stri{ 自动y=StringsProxystri; 名为%s的LOGIURI,y.c_str; 返回setUriDebugOlda1,stri; } 或者反过来说:

StringsProxy assetNameBaseProxy=StringsProxyhttps://example.com/; void setResourceUrluintptr_t*a1,int a2{ *a1+1=*assetNameBaseProxy.ptr; }
这绝对不是一个好的解决方案,但它适用于我的用例。

以下是我目前的想法,真的不理想:

StringsProxy.cc

包括StringsProxy.h 包括 包括 使用名称空间std; __属性\可视性默认值 外部C StringsProxy::StringsProxyconst char*内容 { set_string=std::stringcontents; } __属性\可视性默认值 外部C StringsProxy::StringsProxy{ 设置字符串=*重新解释字符串; } __属性\可视性默认值 外部C常量char*StringsProxy::C_str{ 返回set_string.c_str; } __属性\可视性默认值 外部C常量uintptr_t*StringsProxy::ptr{ 返回reinterpret\u cast和set\u字符串; } __属性\可视性默认值 外部C StringsProxy::~StringsProxy{ } StringsProxy.h

ifndef\uuuu STRINGSPROXY\uH__ 定义字符串Proxy__ 包括 typedef std::基本字符串代理字符串; StringsProxy类 { 公众: /*使用指向现有字符串的指针初始化StringsProxy*/ StringsProxyuintptr_t str; /*使用新字符串初始化StringsProxy*/ StringsProxyconst char*str; /*获取C字符串*/ 虚拟常量字符*c_str; /*获取要注入的字符串的指针*/ const-virtual-uintpttr_*ptr; 私人: 代理字符串集合字符串; }; 恩迪夫 使用带有-DCMAKE\u ANDROID\u STL\u TYPE=gnustl\u static的旧NDK将其编译为共享对象

然后将此共享对象链接到CmakeList中的挂钩程序: 塔吉奥利 nk_库${TARGET_NAME}${CMAKE_CURRENT_SOURCE_DIR}/abiproxy/build/armeabi-v7a/libabiproxy.so

然后在挂钩程序中,可以这样使用:

包括abiproxy/StringsProxy.h void*seturidebuguintpttr\u t a1,uintptpr\u t stri{ 自动y=StringsProxystri; 名为%s的LOGIURI,y.c_str; 返回setUriDebugOlda1,stri; } 或者反过来说:

StringsProxy assetNameBaseProxy=StringsProxyhttps://example.com/; void setResourceUrluintptr_t*a1,int a2{ *a1+1=*assetNameBaseProxy.ptr; }
这绝对不是一个好的解决方案,但它适用于我的用例。

不幸的是,在处理挂接现有应用程序时,我只能使用它们编译时使用的古老NDK。我在上面发布了我的解决方案。不幸的是,在处理挂接现有应用程序时,我被他们编译时使用的古老NDK所困扰。我在上面发布了我的解决方案。通过这种方式,您可以将gnustl字符串从代码中分离出来。看起来还可以,但是为什么不用gnustl和旧NDK重新构建您的整个代码呢?旧NDK有一个内在的文本重新定位问题,正如您所知,现代androids只是拒绝加载带有文本的库_RELOCATIONs@AlexCohn与挂钩库不兼容。这样可以将gnustl字符串与代码隔离。看起来还可以,但是为什么不用gnustl和旧NDK重新构建您的整个代码呢?旧NDK有一个内在的文本重新定位问题,正如您所知,现代androids只是拒绝加载带有文本的库_RELOCATIONs@AlexCohn与挂钩库的某些不兼容。