在非NDK编译条件下使用Android Log函数

解决的需求

有些时候不能在NDK环境编译,或者使用NDK编译会颇费周折,然后又想使用Android系统自带的Log类方法,那么我们就可以使用dlopen来实现我们的目的。比如在OpenCV中添加Android的Log打印。

关于dlopen

  1. dlopen和dlclose对处理的lib进行引用计数,dlopen使引用计数加1,dlclose让引用计数减1,当对库的引用计数达到0的时候,才会把库unmap掉。
  2. dlsym返回查找到的第一个符合要求的函数地址,该地址指的是库加载进进程虚拟地址。
  3. 可以使用dlsym来实现对库的前一个函数的隐藏。There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.
  4. 在调用了dlclose之后,再使用dlsym得到的函数是不行的。虽然当使用dlclose使得引用计数为0之后,系统并不会立马把加载的库给unmap掉,但是这个时间是不确定的。也许在你调用dlclose之后,在系统unmap之前调用dlsym的函数,或者本次dlclose并没有让引用计数为0,比如进程中还有其他地方也dlopen同一个库,那么系统也不会unmap,这样调用dlsym的函数并不会出错。
  5. 如果你想dlopen一个库之后,需要在程序中一直使用这个库的函数,那么没有必要调用dlclose,包括在程序退出之前调用dlclose。因为程序退出会自动unmap这些库。但是如果你要dlopen很多库,可能会导致虚拟地址不足的情况,那么就需要调用dlclose以保证不会出错。https://stackoverflow.com/questions/26131102/is-it-safe-to-call-dlclose-after-dlsym

代码

使用如下代码,实现基于dlopen的Android Log方法调用

#include <dlfcn.h>
#include <stdarg.h>
#define DLLOG_TAG  "Slender3d"

static void logd( const char* format, ...)
{

#ifdef __aarch64__
    const char libpath[] = "/system/lib64/liblog.so";
#else
    const char libpath[] = "/system/lib/liblog.so";
#endif

    const int ANDROID_LOG_DEBUG = 3;

    using __android_log_printFunc = int(*)(int , const char* , const char* , ...);
    static __android_log_printFunc slogFunc = NULL;
    if(NULL == slogFunc){
        void *handler = dlopen(libpath, RTLD_NOW | RTLD_LOCAL);
        dlerror();
        if (handler) {
            const char *SYM = "__android_log_print";
            slogFunc = reinterpret_cast<__android_log_printFunc>(dlsym(handler, SYM));
            char *error;
            if( (error = dlerror() != NULL){
            slogFunc = NULL;
                //LOGE("dlsym %s fail", libpath);
            }
        }
        else {
            //LOGE("dlopen %s fail", libpath);
        }
    }

    if (slogFunc) {
        va_list args;
        va_start(args, format);
        slogFunc(ANDROID_LOG_DEBUG, DLLOG_TAG, format, args);
        va_end(args);
    }
    else {
            //LOGE("dlsym %s fail", SYM);
    }
}

原文地址:https://www.cnblogs.com/willhua/p/11904208.html

时间: 2024-10-09 11:33:50

在非NDK编译条件下使用Android Log函数的相关文章

Ubuntu+NDK编译openssl(为了Android上使用libcurl且支持HTTPS协议)

为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的openssl,它已经提供好了android的ndk makefile.git clone https://github.com/guardianproject/openssl-android.git然后直接cd到该目录,$NDK/ndk-build就行.注意默认的使用NDKr5b,如果没有该版本,请

gradle 编译环境下进行android单元测试

====== android 单元测试介绍 ====== JUnit是一个开源的java单元测试框架,android的测试套件是基于JUnit 3的(不完全兼容JUnit 4),Junit4只需简单了解即可,可以使用普通的junit来进行测试,推荐使用android的Junit测试框架进行高效全面的进行测试. ====== Android 单元测试框架UML ====== {{:dolphin_news:share:androidjunituml.png?300 |}} ====== eclip

使用NDK编译含JNI的Android项目常见问题解决方案

有时候,自己下载的或者拷贝过来的JNI项目出现莫名错误,通常是找不到头文件,可能解决方案如下: Removing the C nature: The only way I could find to reliably removed the C nature from the project was by hand editing Eclipse's .project file for the project. Close the Eclipse project (e.g. by quittin

基于android studio编译工具下的android开发之IBeacon 例子

想直接看主要内容的请调到红字下面. 之所以会接触到android下的IBeacon,是因为我自己导师给的任务.一个网址http://estimote.com/和一句话:看看这个网站,然后试下在安卓手机实现与IBeacon的对接. 在这之前,我从来没听说过IBeacon和BLE技术,点开网站,发现都是英文的,细看才知道是关于IBeacon产品的官网.看了下它们的示范flash,觉得挺吊. 重点: 于是开始着手找资料.首先找的是estimote 的 android-SDK,网址https://git

android ndk编译x264开源(用于android的ffmpeg中进行软编码)

http://blog.csdn.net/u012917616/article/details/40921833 不废话,直接上.sh脚本: export NDK=/home/xxx/my_software/android-ndk-r10 export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ export PLATFORM=$NDK/platforms/android-14/arch-arm export PREF

[原]如何用Android NDK编译FFmpeg

\我们知道在Ubuntu下直接编译FFmpeg是很简单的,主要是先执行./configure,接着执行make命令来编译,完了紧接着执行make install执行安装.那么如何使用Android的NDK编译出来可以在Android下面可以使用的FFmpeg动态链接库呢?写下这篇文章就是学习如何裁剪并且编译出来可以使用的动态库. 一.获取FFmpeg源码: 首先在编译之前,得获取一份FFmpeg的源码,如果你没有git并且也不打算使用,你可以去FFmpeg官网http://ffmpeg.org/

工程文件csproj使用编译条件指定属性

csproj工程文件中有很多xml格式的属性,比如PropertyGroup.ItemGroup,某些属性操作默认是全部的或者是当前编译条件的而已,当我们想指定某些属性只在某个编译条件下发生时就可以通过以下xml属性来指定: Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" 或者 Condition=" '$(Configuration)' == 'Debug' " 例如,Release和Debug

ffmpeg2.2在ubuntu下使用NDK编译——并在android工程下测试使用

作者:wainiwann 出处:http://www.cnblogs.com/wainiwann/ 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 摘要:本文主要介绍将FFmpeg音视频编解码库移植到Android平台上的编译和基本测试过程. 环境准备: Ubuntu12.04 TLS android-ndk-r9d-linux-x86_64.tar.bz2 ffmpeg2.2 --------------------

C++开发安卓、windows下搭建Android NDK开发环境

1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个工具,我们可以把用C/C++代码编译成可以直接运行在Android平台上的本地代码,这些本地代码以动态链接库( *.so )的形式存在,也正因为这样,我们可以通过复用这些动态链接库从而复用本地代码. 那么,通过NDK这个开发工具包,那么我们是否可以将一个APK完全使用C/C++来编写呢? 答案是不可