在非NDK編譯條件下使用Android Log函數

来源:https://www.cnblogs.com/willhua/archive/2020/02/15/11904208.html
-Advertisement-
Play Games

解決的需求 有些時候不能在NDK環境編譯,或者使用NDK編譯會頗費周折,然後又想使用Android系統自帶的Log類方法,那麼我們就可以使用 dlopen 來實現我們的目的。比如在OpenCV中添加Android的Log列印。 關於dlopen 1. dlopen和dlclose對處理的lib進行引 ...


解決的需求

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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ARM 前幾天剛發佈了 Cortex-M 家族最新一款內核 - Cortex-M55 以及首款面向 Cortex-M 系列的 microNPU - Ethos-U55。Cortex-M55 是第一款面向 AI/ML 的 Cortex-M 內核,痞子衡也專門為此寫過一篇小文 《為AI/ML而生(Cor... ...
  • 上一篇文章學習了用戶及文件相關許可權,本篇繼續學習防火牆技術。 ...
  • 一、 使用Java操作Redis前,請先運行Redis服務與下載Redis驅動,以maven工程為例,引入如下jar <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0 ...
  • 這是高級開發者面試時經常被問的問題。實際我們在平時的開發中,經常會遇到的,在用SQLyog等工具創建表時,就有一個引擎項要你去選。如下圖: Mysql的存儲引擎有這麼多種,實際我們在平時用的最多的莫過於InnoDB和MyISAM了。 所有如果面試官問道mysql有哪些存儲引擎,你只需要告訴這兩個常用 ...
  • 大數據技術體系的知識量是比較大的,而且涉及到的內容也具有一定的難度,對於初學者的知識結構還是有一定要求的。通常來說,要想學習大數據技術,需要具有一定的數學和電腦基礎,如果具有一定的統計學基礎會更好一些。 ...
  • 問題概述 "新冠期間"遠程辦公,需要重新搭建一套ClouderaManager(CM)開發環境,一位測試同事發現HBase的RegionServer無法啟動,在CM界面上啟動總是失敗,觀察一下日誌,也沒有什麼明顯的報錯。我就專門看了一下。 排查思路 1. 因為有opentsdb在讀寫Hbase Re ...
  • 創建 test 測試表 CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `c1` varchar(10) DEFAULT NULL, `c2` varchar(10) DEFAULT NULL, `c3` varchar(10) ...
  • 1、何為explain執行計劃? 使用explain關鍵字可以模擬優化器執行SQL語句,從而知道MySQL是如何使用索引來處理你的SQL查詢語句以及連接表,可以分析查詢語句或是結構的性能瓶頸,幫助我們選擇更好的索引和寫出更優化的查詢語句。(說白了,就是優化SQL的工具) 2、如何使用explain? ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...