小编Mer*_*ert的帖子

如何使用c ++ 11支持为android作为共享库构建boost

我正在尝试使用c ++ 11支持为android构建boost_1.60.0(作为共享库).我正在使用最新的ndk(目前是android-ndk-r10e).构建主机是Windows-10.

这适用于非开源项目.所以据我所知,我不能使用gnustl_shared,我需要使用c ++ _ shared作为android c ++运行时.

我的project-config.jam看起来像这样:

androidNDKRoot = c:/android-ndk-r10e ;
 using gcc : android :
     $(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ :
      <root>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/
      <compileflags>-MMD
      <compileflags>-MP
      <compileflags>-MF
      <compileflags>-fpic 
      <compileflags>-ffunction-sections 
      <compileflags>-funwind-tables 
      <compileflags>-fstack-protector 
      <compileflags>-no-canonical-prefixes 
      <compileflags>-march=armv5te 
      <compileflags>-mtune=xscale 
      <compileflags>-msoft-float 
      <compileflags>-fno-rtti 
      <compileflags>-mthumb 
      <compileflags>-Os 
      <compileflags>-g 
      <compileflags>-DNDEBUG 
      <compileflags>-fomit-frame-pointer 
      <compileflags>-fno-strict-aliasing 
      <compileflags>-finline-limit=64
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../llvm-libc++abi/libcxxabi/include
      <compileflags>-IC:/android-ndk-r10e/sources/cxx-stl/llvm-libc++/../../android/support/include
      <compileflags>-IC:/android-ndk-r10e/platforms/android-9/arch-arm/usr/include
      <compileflags>-Wa,--noexecstack 
      <compileflags>-Wformat 
      <compileflags>-Werror=format-security
      <compileflags>-DUNIX 
      <compileflags>-DANDROID 
      <compileflags>-Wl,--no-undefined
      <cxxflags>-fexceptions 
      <linkflags>-lc++_shared
      <archiver>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-ar
      <ranlib>$(androidNDKRoot)/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-ranlib
        ;        
Run Code Online (Sandbox Code Playgroud)

build命令是:

b2 --toolset=gcc-android cxxflags="-std=c++11 " --prefix=..\boost_android_arm --builddir=./boost_android_arm/builddir target-os=linux --with-filesystem define=BOOST_FILESYSTEM_VERSION=3 link=shared runtime-link=shared threading=multi 
Run Code Online (Sandbox Code Playgroud)

为了确定project-config.jam中的参数,我使用ndk-build构建了一个示例共享库,获取了它的调试消息,并提取了它使用的编译和链接命令.

编译:

C:\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-g++.exe,C:/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi/objs/someLib/./Unity1.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector …
Run Code Online (Sandbox Code Playgroud)

c++ android boost android-ndk c++11

16
推荐指数
2
解决办法
7820
查看次数

避免在Boost Log中使用漏洞

我从服务器端应用程序获得valgrind泄漏报告,该应用程序使用与boost 1.56一起分发的boostlog.valgrind报告是:

== 8021 == 1,159块中的37,088字节肯定会在1,642的损失记录1,613中丢失

== 8021 ==在0x4A05588:memalign(vg_replace_malloc.c:727)

== 8021 == by 0x3FDA61118F:tls_get_addr_tail(在/lib64/ld-2.12.so中)

== 8021 == by 0x3FDA61165F:__ tls_get_addr(在/lib64/ld-2.12.so中)

== 8021 == by 0x3FE6ABBDCB:__ cxa_get_globals(在/usr/lib64/libstdc++.so.6.0.13中)

== 8021 == by 0x730C528:boost :: log :: v2_mt_posix :: aux :: unhandled_exception_count()(在/opt/sesteksdk/lib/libboost_log.so.1.56.0中)

== 8021 == by 0x5D54D1F:sestek :: mrcp :: audio :: recognition :: AsynchronousRecognizer :: Notify(sestek :: voice :: recognition :: IRecognizerNotification const*)(record_ostream.hpp:259)

这种泄漏来自一条简单的线路:
LOGGER(debug)<< _chanProp->GetId() << " got recognition ended notification from recognizer";

我们从一次短暂的测试运行中得到了5个泄漏.

我们使用文本文件后端,同步接收器,自动刷新打开.基本上:

void InitializeFileLog(const std::string & logDir)
    { …
Run Code Online (Sandbox Code Playgroud)

c++ logging boost memory-leaks boost-log

13
推荐指数
1
解决办法
1518
查看次数

我应该以哪种顺序发送callback()并通知服务员?

我有一个类,通过它我可以异步提供一些服务(同样的调用也可以同步进行).当请求时,此类的对象(比如运算符)在另一个线程中启动操作.其他对象可以注册到操作符对象的通知,以便在操作结束时对此对象调用OperationEnded()方法.其他对象也可以通过调用操作符对象上的Wait()来等待此操作的完成.

操作结束时的代码大致如下:

_opEndedMutex.lock();
_thereIsOngoingOp = false;
_opEndedCondition.notify_all();
_opEndedMutex.unlock();

//no more call after notification
m_spNotificationManager->OperationEnded();
Run Code Online (Sandbox Code Playgroud)

而wait()函数如下:

boost::unique_lock<boost::mutex> lock(_opEndedMutex);
while(_thereIsOngoingOp)
{
    _opEndedCondition.wait(_opEndedMutex);
}
Run Code Online (Sandbox Code Playgroud)

问题在于资源管理.这是一个C++类,因此当检测到操作结束时,此类的用户可能会删除操作符对象(如果存在任何活动操作,析构函数将等待完成).可以通过等待或接受通知来检测操作的结束.因此,如果我首先调用_opEndedCondition.notify_all()并且用户删除操作符对象,则在尝试调用OperationEnded()时可能会崩溃,因为m_spNotificationManager已被删除.如果选择首先调用OperationEnded()并且用户在此调用期间删除操作符对象,则在尝试访问_opEndedMutex,_thereIsOngoingOp和_opEndedCondition时可能会崩溃.

我想到的第一件事就是使用新的互斥锁来保护这两个调用.这看起来并不漂亮,因为我无法预见如果引入新的互斥锁会发生什么,并且如果在OperationEnded()通知中用户同步启动新操作.我也不确定如何在wait()方法中使用新的互斥锁.

注1:此API用于我们自己公司和其他公司的应用程序.所以我无法摆脱任何一种同步机制.

注意2:我修改了原始代码,变量和方法名称,因此可能存在拼写错误,但这个想法应该是明确的.

EDIT1:

操作员对象保留在通过工厂生成的共享库中,然后通过接口暴露给外部世界.所以操作符对象的典型生命周期如下:

IOperator * op = factory:getNewOperator();
//perform operations with op
op->Release() //this one goes and deletes the op object
Run Code Online (Sandbox Code Playgroud)

另请注意,运算符对象是可重用的.客户端代码可以使新的操作符对象多次使用它并在最后删除它.

c++ multithreading thread-safety

7
推荐指数
1
解决办法
208
查看次数