宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述在非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"
;
#endifconst 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);
}
}
推荐阅读
- Mapper 文件中SQL不等于的写法
- 安卓记账本开发——图表的使用
- uniapp简易直播
- 宝宝乖 app
- Android Studio学习路程(10)
- oracle 11g未找到文件WFMLRSVCApp.ear文件
- qml-main.cpp中的两种启动Qt Quick App模式
- 016-Android获取onenet平台上的数据
- Android Studio学习路程(11)