1.miniui详解
2.深入分析linux下 动态库的源码显性调用(dlopen)和隐性调用区别
3.一种简单加载vulkan动态库的方法
4.android dlopenååå¨åªä¸ªso
miniui详解
在Android源码中,为了实现adb调用的源码多个Linux可执行程序,涉及到miniui框架的源码编写与应用。以下是源码miniui框架的详细介绍。
miniui是源码一个由Android提供的用于简单UI输出的库,其源码位于factory/src/minui目录下。源码如何制作源码边框
此库包含关键函数如gr_init()和gr_font_size()。源码gr_init()用于准备UI输出环境,源码而gr_font_size()则提供获取字体大小的源码功能。
进一步了解,源码miniui库还提供了res_create_surface()函数,源码用于将转换为表面。源码teambition 源码
使用miniui时,源码主程序通常通过dlopen()加载一个.so动态库文件。源码动态库在运行时自动执行_init()初始化函数,源码该函数输出提示信息,并调用主程序的注册函数以重新赋值给结构体。随后,结构体的函数指针被调用,以打印结构体的值。这种机制实现了主程序与动态库之间的函数调用和指针传递。
关于miniui的使用和功能介绍,本文仅提供基础信息,websocketserver源码后续内容将不断更新,敬请期待。
深入分析linux下 动态库的显性调用(dlopen)和隐性调用区别
在Linux环境下编程时,使用第三方库有多种方式。主要可以分为四类:合并源码、使用静态库、隐性调用动态库和显性调用动态库。
合并源码和使用静态库的实质相同,静态库在编译时被合并到项目中,当无法获取第三方库源码时,静态库提供了一个黑盒解决方案。unrar 源码而隐性调用动态库和显性调用动态库则属于动态库使用范畴,其中隐性调用动态库在程序执行前检查并加载动态库,显性调用动态库在程序执行过程中仅在使用到相关函数时才加载动态库。
隐性调用动态库需要将动态库文件拷贝至特定目录,无论程序是否真正使用该动态库,检查和加载动态库在执行前已完成,而动态库会一直驻留在内存中。显性调用动态库则无需在程序执行前加载动态库文件,仅在程序调用相关函数时动态加载,提供了一种灵活的插件式加载机制。
为直观对比这四种方式的daseygenius源码内存占用情况,可以设计一个简单的测试场景。实现一个包含加、减、乘、除、打印等功能的计算库,主程序调用此库。通过监控内存使用情况,可以观察到显性调用动态库时,dlopen前动态库文件并未读入内存,只有在执行dlopen后,动态库文件才被加载到内存中。
在进行测试时,分别采取源码、静态库、隐性动态调用和显性动态调用的方式,对比内存使用情况。在源码方式下,内存占用约为kb;静态库调用内存占用与源码方式相同;隐性动态调用内存变化不大,但内存中已包含libcalculate.so;而显性动态调用内存增加到kb,表明动态库仅在实际使用时才被加载。
总结而言,显性调用动态库更适合于需要按需加载功能的大型项目,提供了一种内存和磁盘占用更为灵活的解决方案,但使用上相对复杂,需要额外的代码转换。相比之下,隐性调用动态库在内存使用上更为简洁,但可能会导致动态库的无谓加载。在实际生产环境中,若对内存、磁盘空间和启动速度没有特别要求,推荐使用隐性调用动态库,以简化程序编写和维护。
一种简单加载vulkan动态库的方法
在适配国产Linux环境的vulkan应用时,常需面对系统自带libvulkan.so.1但缺失libvulkan.so的困境。若系统源缺少vulkan SDK或loader,需手工下载并编译,步骤繁琐且涉及依赖安装与CMake升级。为简化流程,实现快速测试vulkan兼容性和调试应用,本文提出一种简易加载vulkan动态库的方法,无需安装vulkan SDK或loader,直接利用系统中自带的libvulkan.so.1。
基本原理在于初始化阶段,通过dlopen和dlsym加载vulkan动态库中的api函数指针,应用程序直接调用这些api。本文采用了一个开源的动态库加载工具dylib,支持多系统平台。以vkCreateInstance函数地址的加载为例,需注意vkCreateInstance在vulkan_core.h中的声明被宏VK_NO_PROTOTYPES括起。在CMake中添加该宏定义(add_definitions(-DVK_NO_PROTOTYPES)),阻止vulkan_core.h对原生vk api进行声明。这样,可在load.h中对原生vulkan api进行声明,实现动态库加载。
整个load.h源码示例如下,应用于app初始化时调用vk_loader_init(),实现vulkan动态库中所有函数地址的加载。测试demo项目的地址提供于此。
android dlopenååå¨åªä¸ªso
1ã .soæåº
使ç¨gccæè g++ç¼è¯å¨æåºæ件(å¤g++ç¼è¯å¨ä¾)
g++ -shared -fPIC -c XXX.cpp
g++ -shared -fPIC -o XXX.so XXX.o
2ã .soæåºæè°ç¨æ¥å£å½æ°è¯´æ
æåºè°ç¨å ³ç³»éè¦è°ç¨æåºç¨åºç¼è¯ég++-L-lå½ä»¤æå®ä¾ï¼ç¨åºtestå¯éè¦å è½½ç®å½/root/src/liblibtest_so1.soæåºç¼è¯å½ä»¤ç §ç¼åæ§è¡ï¼
g++ -g -o test test.cpp âL/root/src/lib âltest_so1
ï¼å¤æéç¹è®²è§£æåºæè°ç¨å ³äºéæég++ç¼è¯å½ä»¤è°ç¨å¼ä½è¯¦ç»è®²è§£å ·ä½ç¸å ³å 容ç½æ¥è¯¢)
Linuxæä¾ä¸é¨ç»APIç¨äºå®ææåºæ¥æ¾ç¬¦å·å¤çéå ³éæåºçåè½
é¢äºæ¥å£å½æ°éä»ç»ï¼è°ç¨äºæ¥å£éå¼ç¨æ件#include )ï¼
1) dlopen
å½æ°ååï¼void *dlopen(const char *libname,int flag);
åè½æè¿°ï¼dlopenå¿ é¡»dlerrordlsymdlcloseåè°ç¨è¡¨ç¤ºè¦åºè£ è½½å ååå¤ä½¿ç¨è¦è£ è½½åºä¾èµäºå ¶åºå¿ é¡»é¦å è£ è½½ä¾èµåºdlopenæä½å¤±è´¥è¿NULLå¼ï¼åºå·²ç»è£ è½½ådlopenè¿åå¥æ
åæ°libnameè¬åºå ¨è·¯å¾dlopenç´æ¥è£ 载该æ件ï¼æå®åºå称dlopenæç §é¢æºå¶æ寻ï¼
a.æ ¹æ®ç¯å¢åéLD_LIBRARY_PATHæ¥æ¾
b.æ ¹æ®/etc/ld.so.cacheæ¥æ¾
c.æ¥æ¾ä¾/lib/usr/libç®å½æ¥æ¾
flagåæ°è¡¨ç¤ºå¤çæªå®ä¹å½æ°å¼ä½¿ç¨RTLD_LAZYæRTLD_NOWRTLD_LAZY表示æå¤çæªå®ä¹å½æ°å åºè£ è½½å åçç¨æ²¡å®ä¹å½æ°å说ï¼RTLD_NOW表示马æ£æ¥å¦åæªå®ä¹å½æ°è¥åådlopen失败åç»
2) dlerror
å½æ°ååï¼char *dlerror(void);
åè½æè¿°ï¼dlerrorè·è¿dlopen,dlsymædlcloseæä½é误信æ¯è¿NULL表示é误dlerrorè¿é误信æ¯åæ¸ é¤é误信æ¯
3) dlsym
å½æ°ååï¼void *dlsym(void *handle,const char *symbol);
åè½æè¿°ï¼dlopenåºè£ è½½å ådlsymè·æå®å½æ°(symbol)å åä½ç½®(æé)æ¾æå®å½æ°ådlsymè¿NULLå¼å¤æå½æ°å¦å使ç¨dlerrorå½æ°
4) dlclose
å½æ°ååï¼int dlclose(void *);
åè½æè¿°ï¼å·²ç»è£ è½½åºå¥æåå¥æåè³é¶å该åºå¸è½½åææå½æ°ådlcloseææå½æ°è°ç¨
3ã æ®éå½æ°è°ç¨
å¤æºç å®ä¾è¯´æåæºç æä»¶å ³ç³»ï¼
test_so1.htest_so1.cpptest_so1.soæåº
test_so2.htest_so2.cpptest_so2.soæåº
test_dl.cpptest_dlæ§è¡ç¨åºtest_dlédlopenç³»åçAPIå½æ°å¹¶ä½¿ç¨å½æ°æéè¾¾æè°ç¨åsoåºtestå½æ°ç®
-