函数load也是实现在文件hardware/libhardware/hardware.c文件中,如下所示:

  1. staticintload(constchar*id,
  2. constchar*path,
  3. conststructhw_module_t**pHmi)
  4. {
  5. intstatus;
  6. void*handle;
  7. structhw_module_t*hmi;
  8. /*
  9. *loadthesymbolsresolvingundefinedsymbolsbefore
  10. *dlopenreturns.SinceRTLD_GLOBALisnotor'dinwith
  11. *RTLD_NOWtheexternalsymbolswillnotbeglobal
  12. */
  13. handle=dlopen(path,RTLD_NOW);
  14. if(handle==NULL){
  15. charconst*err_str=dlerror();
  16. LOGE("load:module=%s\n%s",path,err_str?err_str:"unknown");
  17. status=-EINVAL;
  18. gotodone;
  19. }
  20. /*Gettheaddressofthestructhal_module_info.*/
  21. constchar*sym=HAL_MODULE_INFO_SYM_AS_STR;
  22. hmi=(structhw_module_t*)dlsym(handle,sym);
  23. if(hmi==NULL){
  24. LOGE("load:couldn'tfindsymbol%s",sym);
  25. status=-EINVAL;
  26. gotodone;
  27. }
  28. /*Checkthattheidmatches*/
  29. if(strcmp(id,hmi->id)!=0){
  30. LOGE("load:id=%s!=hmi->id=%s",id,hmi->id);
  31. status=-EINVAL;
  32. gotodone;
  33. }
  34. hmi->dso=handle;
  35. /*success*/
  36. status=0;
  37. done:
  38. if(status!=0){
  39. hmi=NULL;
  40. if(handle!=NULL){
  41. dlclose(handle);
  42. handle=NULL;
  43. }
  44. }else{
  45. LOGV("loadedHALid=%spath=%shmi=%phandle=%p",
  46. id,path,*pHmi,handle);
  47. }
  48. *pHmi=hmi;
  49. returnstatus;
  50. }
在Linux系统中,后缀名为"so"的文件为动态链接库文件,可能通过函数dlopen来加载到内存中。硬件抽象层模块编写规范规定每一个硬件抽象层模块都必须导出一个符号名称为HAL_MODULE_INFO_SYM_AS_STR的符号,而且这个符号必须是用来描述一个类型为hw_module_t的结构体的。 HAL_MODULE_INFO_SYM_AS_STR是一个宏,定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:
  1. #defineHAL_MODULE_INFO_SYM_AS_STR"HMI"

将Gralloc模块加载到内存中来之后,就可以调用函数dlsym来获得它所导出的符号HMI。由于这个符号指向的是一个hw_module_t结构体,因此,最后函数load就可以强制地将这个符号转换为一个hw_module_t结构体指针,并且保存在输出参数pHmi中返回给调用者。调用者获得了这个hw_module_t结构体指针之后,就可以创建一个gralloc设备或者一个fb设备。

模块Gralloc实现在目录hardware/libhardware/modules/gralloc中,它导出的符号HMI定义在文件hardware/libhardware/modules/gralloc/gralloc.cpp文件中,如下所示:

  1. staticstructhw_module_methods_tgralloc_module_methods={
  2. open:gralloc_device_open
  3. };
  4. structprivate_module_tHAL_MODULE_INFO_SYM={
  5. base:{
  6. common:{
  7. tag:HARDWARE_MODULE_TAG,
  8. version_major:1,
  9. version_minor:0,
  10. id:GRALLOC_HARDWARE_MODULE_ID,
  11. name:"GraphicsMemoryAllocatorModule",
  12. author:"TheAndroidOpenSourceProject",
  13. methods:&gralloc_module_methods
  14. },
  15. registerBuffer:gralloc_register_buffer,
  16. unregisterBuffer:gralloc_unregister_buffer,
  17. lock:gralloc_lock,
  18. unlock:gralloc_unlock,
  19. },
  20. framebuffer:0,
  21. flags:0,
  22. numBuffers:0,
  23. bufferMask:0,
  24. lock:PTHREAD_MUTEX_INITIALIZER,
  25. currentBuffer:0,
  26. };

HAL_MODULE_INFO_SYM也是一个宏,它的值是与宏HAL_MODULE_INFO_SYM_AS_STR对应的,它也是定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:
图1 private_module_t结构体定义

结构体private_module_t的第一个成员变量base指向一个gralloc_module_t结构体,而gralloc_module_t结构体的第一个成员变量common又指向了一个hw_module_t结构体,这意味着,指向一个private_module_t结构体的指针同时可以用作一个gralloc_module_t或者hw_module_t结构体提针来使用。事实上,这是使用C语言来实现的一种继承关系,等价于结构体private_module_t继承结构体gralloc_module_t,而结构体gralloc_module_t继承hw_module_t结构体。这样,我们就可以把在Gralloc模块中定义的符号HAL_MODULE_INFO_SYM看作是一个hw_module_t结构体。

hw_module_t结构体有一个重要的成员变量methods,它的类型为hw_module_methods_t,它用来描述一个HAL模块的操作方法列表。结构体hw_module_methods_t只定义有一个操作方法open,用来打开一个指定的设备。在Gralloc模块中,用来打开指定设备的函数被指定为gralloc_device_open,通过这个函数就可以打开Gralloc模块中的gralloc或者fb设备,后面我们再详细分析。

更多相关文章

  1. android 读写私有文件
  2. Android(安卓)SwipeMenuListView策滑实现各种删除和打开功能
  3. No usable Android(安卓)build tools found. Highest installed
  4. android-ndk-r6b编译NDK
  5. Android(安卓)资源文件错误排查 Process 'command ' 等错误排查
  6. Android实现文件目录的选择并保存到SharedPreferences中(适配6.0
  7. unity调用aar包 适配AndroidX冲突
  8. Develop--Training(五)Getting Started--Saving Data
  9. apk 反编译 教程 (不支持混淆,Android)

随机推荐

  1. 关于Android(安卓)studio的build.gradle
  2. windows下Android开发环境配置
  3. Android手机用户隐私获取,包括读取通讯录
  4. Android(安卓)UI绘制 - 动画基础
  5. AndroidStudio用gradle编译中文乱码
  6. ReactNative Android/iOS 打包详情流程
  7. Android(安卓)开发者学习路线(2020 版)
  8. Android选项卡Tab的实现
  9. android修改手机默认音量配置
  10. 【Android】Android(安卓)彩信发送的两种