使用libhybris库让linux调用android库

Android 是基于 Linux 的 OS,所以想要在 ARM 的 Linux 上,比如树莓派,是有可能的。但事实上其中还是有问题,主要是因为 Android 的 so 库是通过 Bionic libc 代替了 glibc 作为标准库,两者有很多的差别,无法直接移用。

为了解决这个问题,出现了 libhybris 这个库,其主要作用是将 Android 库对 Bionic libc 的方法引用,Link 到 glibc 上,以实现对 Android 库在 ARM Linux 上的支持。libhybris 原来是用于让各 Linux 发行版支持 Android 的驱动,比如 Ubuntu Touch 和 Sailfish OS 都是使用这个库来兼容 Android 设备的。原理图如下:

libhybris 原理图

libhybris主要作用是为了解决libc库的兼容问题,目的是为了在基于GNU C library的系统运行那些用bionic编译的库(主要是Android下的闭源HAL库)。它在Ubuntu touch, WebOS, Jolla Sailfish OS等系统中都有使用。因为这些系统都是基于glibc生态的,然而现有的硬件厂商提供的driver多是为Android而写的,自然也是用bionic编译的。那么问题来了,说服厂商再写一套驱动不是那么容易的,就算写出来也需要经过一段时间才能变得成熟。那如何让基于glibc的系统能够重用现有Android的driver呢?这就需要像libhybris这样的兼容层。

1、库的编译
              首先你需要准备一套跑linux系统的arm架构机器,最好装最新的debian或ubuntu系统。这样编译是不会出一些奇怪的错误

下载libhybris源码
# git clone  https://github.com/libhybris/libhybris.git
# ./autogen.sh

如果出现checking for android-headers...no。停止,并没有生成Makefile文件。下面给你解决,如果是其他错误请自行百度(一般都是环境没好)

这个android-headers是什么东西呢,我也搞了好久,不过在源码的utils/extract-headers.sh中发现有android-headers字样

ANDROID_ROOT 当然是android源码咯, android-headers可以去ubuntu系统官网下载

下载后运行脚本

提取android头文件
# ./extract-headers.sh  android-aosp/  /tmp/android-headers/  4 2 2  
这里4 2 2编译不过,就去掉了4 2 2 ,
然后在android-headers目录
# make install。

之后再回到libhybris运行./autogen.sh ,无错误。make 编译后有libandroid-properties.so、libhybris-common.so。将其拷贝置/usr/lib文件目录下,include文件拷贝到、/usr/include目录下。当然你可以用make install ,只是其他库我不知道用,所以没有拷贝

之后再在根目录下新建/system/lib64目录(我系统是64位的)此目录下存放android的库及其依赖库。将android的build.prop拷贝置system目录下

2、库的使用
Android.mk:

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= libfoo

LOCAL_SRC_FILES:= foo.cpp

include $(BUILD_SHARED_LIBRARY)

foo.cpp:

#include <stdio.h>

#include <stdlib.h>

void foo(void)

{

printf("foo\n");

printf("%s\n", getenv("PATH"));

}

void bar(void)

{

foo();

printf("bar\n");

}
android库拷贝至linux系统的/system/lib64目录下

通过libhybris,调用bar函数:

#include <stdio.h>

#include <hybris/common/dlfcn.h>

#include <string.h>

#include <errno.h>

int main(void)

{

void *handle;

void (*bar)(void);

handle = hybris_dlopen("libfoo.so", RTLD_NOW);

if (NULL == handle)

{

fprintf(stderr, "android_dlopen failed: %s\n", strerror(errno));

return -1;

}

bar = (void (*)(void))hybris_dlsym(handle, "_Z3barv");

if (NULL == bar)

{

fprintf(stderr, "fail to dlsym: %s\n", strerror(errno));

return -1;

}

bar();

return 0;

}
发布了766 篇原创文章 · 获赞 474 · 访问量 254万+

猜你喜欢

转载自blog.csdn.net/u010164190/article/details/105533354