在非NDK编译条件下使用Android Log函数
解决的需求
有些时候不能在NDK环境编译,或者使用NDK编译会颇费周折,然后又想使用Android系统自带的Log类方法,那么我们就可以使用dlopen来实现我们的目的。比如在OpenCV中添加Android的Log打印。
关于dlopen
- dlopen和dlclose对处理的lib进行引用计数,dlopen使引用计数加1,dlclose让引用计数减1,当对库的引用计数达到0的时候,才会把库unmap掉。
- dlsym返回查找到的第一个符合要求的函数地址,该地址指的是库加载进进程虚拟地址。
- 可以使用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.
- 在调用了dlclose之后,再使用dlsym得到的函数是不行的。虽然当使用dlclose使得引用计数为0之后,系统并不会立马把加载的库给unmap掉,但是这个时间是不确定的。也许在你调用dlclose之后,在系统unmap之前调用dlsym的函数,或者本次dlclose并没有让引用计数为0,比如进程中还有其他地方也dlopen同一个库,那么系统也不会unmap,这样调用dlsym的函数并不会出错。
- 如果你想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函数的更多相关文章
- 浅谈独立使用NDK编译库文件(Android)
阅读前准备 这是一篇相对入门的文章.文中会涉及到少许NDK的知识,但个人认为对初学者来说都相对比较实用,因为都是在平时项目中遇到的(目前自己也是初学者).一些其他高深的技术不再本文探讨范围之内(因为我 ...
- ndk编译时的通用Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := live555 MY_SRC_PATH := $(LOCAL_PA ...
- Ubuntu+NDK编译openssl(为了Android上使用libcurl且支持HTTPS协议)
为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的o ...
- 基于android studio编译工具下的android开发之IBeacon 例子
想直接看主要内容的请调到红字下面. 之所以会接触到android下的IBeacon,是因为我自己导师给的任务.一个网址http://estimote.com/和一句话:看看这个网站,然后试下在安卓手机 ...
- 使用NDK编译含JNI的Android项目常见问题解决方案
有时候,自己下载的或者拷贝过来的JNI项目出现莫名错误,通常是找不到头文件,可能解决方案如下: Removing the C nature: The only way I could find to ...
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
http://blog.csdn.net/u012917616/article/details/40921833 不废话,直接上.sh脚本: export NDK=/home/xxx/my_softw ...
- [原]如何用Android NDK编译FFmpeg
我们知道在Ubuntu下直接编译FFmpeg是很简单的,主要是先执行./configure,接着执行make命令来编译,完了紧接着执行make install执行安装.那么如何使用Android的ND ...
- 工程文件csproj使用编译条件指定属性
csproj工程文件中有很多xml格式的属性,比如PropertyGroup.ItemGroup,某些属性操作默认是全部的或者是当前编译条件的而已,当我们想指定某些属性只在某个编译条件下发生时就可以通 ...
- Android NDK开发 Jni中打日志LOG(二)
HelloJni.c文件中,加入头文件和函数声明.最终文件如下: #include <jni.h> #include <string.h> #include<androi ...
随机推荐
- selenium常见的元素定位方法
一.获取元素 1)通过谷歌浏览器自动的工具访问百度首页,我们可以看到,页面上的元素都是由一行行的代码组成的,它们之间有层级地组织起来,每个元素之间都有不同的标签和值,我们可以通过这些不同的标签和值来找 ...
- Python 判断小数的函数
需求分析:1.小数点个数可以使用.count()方法2.按照小数点进行分割 例如: 1.98 [1,98]3.正小数:小数点左边是整数,右边也是整数 可以使用.isdigits()方法4.负小数:小数 ...
- 《阿k学Python》一Python入门(一)
前言 各位看博客的园友们,大家好,我就是那个风流倜傥的KK,还记得我那篇2019年的年中总结博客吗?我想有许多看博客的园友是没有读过我那篇文章的,KK很生气,后果很严重(开个玩笑了,怎么可能).给大家 ...
- Python3-ORM-Sqlalchemy
目录: ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 1. ORM介绍 orm英文全称object relational mapping, ...
- vscode写python时的代码错误提醒和自动格式化
python的代码错误检查通常用pep8.pylint和flake8,自动格式化代码通常用autopep8.yapf.black.这些工具均可以利用pip进行安装,这里介绍传统的利用pip.exe安装 ...
- nmap详解之基础示例
扫描主机target.example.com的所有TCP端口 nmap -v target.example.com 发起对target.example.com所在网络上的所有255个IP地址的秘密SY ...
- Docker基础内容之镜像
概念 镜像是一个包含程序运行必要依赖环境和代码的只读文件,它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 下图展示的是Docker镜像的系统结构.其中, ...
- Kafka网络模型和通信流程剖析
1.概述 最近有同学在学习Kafka的网络通信这块内容时遇到一些疑问,关于网络模型和通信流程的相关内容,这里笔者将通过这篇博客为大家来剖析一下这部分内容. 2.内容 Kafka系统作为一个Messag ...
- phpstrom激活码
今天PHPstorm又到期了,从网上找到一个激活码的网址,很好用,说是会时时更新的,所以特意记录一下 获取地址:https://www.php.cn/tool/phpstorm/408348.html
- 实验18:HDLC和PPP
实验15-1:HDLC 和PPP 封装 Ø 实验目的通过本实验,读者可以掌握如下技能:(1) 串行链路上的封装概念(2) HDLC 封装(3) PPP 封装 Ø 实验拓扑 实验步骤n ...