解决的需求

有些时候不能在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);
}
}

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

  1. 浅谈独立使用NDK编译库文件(Android)

    阅读前准备 这是一篇相对入门的文章.文中会涉及到少许NDK的知识,但个人认为对初学者来说都相对比较实用,因为都是在平时项目中遇到的(目前自己也是初学者).一些其他高深的技术不再本文探讨范围之内(因为我 ...

  2. ndk编译时的通用Android.mk文件

    LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := live555 MY_SRC_PATH := $(LOCAL_PA ...

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

    为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的o ...

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

    想直接看主要内容的请调到红字下面. 之所以会接触到android下的IBeacon,是因为我自己导师给的任务.一个网址http://estimote.com/和一句话:看看这个网站,然后试下在安卓手机 ...

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

    有时候,自己下载的或者拷贝过来的JNI项目出现莫名错误,通常是找不到头文件,可能解决方案如下: Removing the C nature: The only way I could find to ...

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

    http://blog.csdn.net/u012917616/article/details/40921833 不废话,直接上.sh脚本: export NDK=/home/xxx/my_softw ...

  7. [原]如何用Android NDK编译FFmpeg

    我们知道在Ubuntu下直接编译FFmpeg是很简单的,主要是先执行./configure,接着执行make命令来编译,完了紧接着执行make install执行安装.那么如何使用Android的ND ...

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

    csproj工程文件中有很多xml格式的属性,比如PropertyGroup.ItemGroup,某些属性操作默认是全部的或者是当前编译条件的而已,当我们想指定某些属性只在某个编译条件下发生时就可以通 ...

  9. Android NDK开发 Jni中打日志LOG(二)

    HelloJni.c文件中,加入头文件和函数声明.最终文件如下: #include <jni.h> #include <string.h> #include<androi ...

随机推荐

  1. Collections中的常用方法

    collections中的常用方法 public class CollectionsTest { public static void main(String[] args) { List list ...

  2. Dynamics 365 CRM 在 Connected Field Service 中部署 IoT Central (二)- 匹配设备

    上个blog中介绍了我们怎么去部署IoT central和 connected field service做连接. 我们这次介绍怎么把IoT设备在CRM中怎么去注册. 首先我们打开devices,再选 ...

  3. laravel 工厂模式到容器

    下面实现了查人拥有超能力的三种方式 第一种最基本的类引用实现 1 <?php /** * 目的:代码的完善来说明从 基础类的调用到 工厂类的使用 再到容器的出现的原因 * (首先要明白工厂类和容 ...

  4. springIOC源码接口分析(十一):ConfigurableApplicationContext

    一 实现接口 关系图: ConfigurableApplicationContext接口实现了三个接口,ApplicationContext, Lifecycle, Closeable, Applic ...

  5. Spring Cloud中Eureka注册显示UNKNOWN问题

    这是由于application.yml里spring没有配置实例造成的

  6. IntelliJ IDEA 2019.3 安装+永久破解[Windows]

    IntelliJ IDEA 2019的最后一个版本发布了,听说大幅优化了运行速度,本人实测启动速度确实比以前快不少,所以赶紧安排上新版本IDEA的破解教程 系统环境:Win10 LTSC(1809) ...

  7. java代码之美(14)---Java8 函数式接口

    Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加 ...

  8. ceph问题

    问题1: [root@admin-node my-cluster]# ceph -s cluster 4ca35731-2ccf-47fb-9f06-41fae858626d health HEALT ...

  9. css- :before :after

    :before和:after的作用就是在指定的元素内容(而不是元素本身)之前或者之后插入一个包含content属性指定内容的行内元素,最基本的用法如下: #example:before { conte ...

  10. 导弹拦截(dp复习)

    题目描述:求最长下降子序列的长度 in: 71 7 3 5 9 4 8 out: 4 解释:1 3 4 8/1 3 5 8 长度为四 这让我想到了hdu上导弹拦截那道题,是求最长上升子序列长度 其转移 ...