Android Binder(C语言版本例子)

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder(C语言版本例子)相关的知识,希望对你有一定的参考价值。

 cmds/servicemanager/godv_server.c

/* Copyright 2008 The android Open Source Project
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "binder.h"
#include "godv_server.h"

void sayhello(void)
{
    static int cnt = 0;

    fprintf(stderr, "sayhello : %d\\n",cnt++);
}

int sayhello_to(char *name)
{
    static int cnt = 0;

    fprintf(stderr, "sayhello_to %s : %d\\n",name,cnt++);
    return cnt;
}


int godv_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{

    //根据txn->code知道要调用哪个函数
    //如果需要参数可以从*msg中取
    //返回结果*reply

    //提供两个参数  一个sayhello  一个sayhelloto


    uint16_t *s;
    size_t len;
    uint32_t strict_policy;
    struct binder_state *bd;
    bd = bs;


    strict_policy = bio_get_uint32(msg);
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
    }

    char name[512];
    unsigned i;
    int b;

    switch(txn->code) {
    case HELLO_SVR_CMD_SAYHELLO:
        sayhello();
        break;
    case HELLO_SVR_CMD_SAYHELLO_TO:
    //从*msg中取出字符串
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        for(i = 0; i<len; i++){
            name[i] = s[i];
        }
        name[i] = '\\0';
        //调用函数
        b = sayhello_to(name);
        //返回结果
        bio_put_uint32(reply, b);
        break;
    default:
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}

uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
        return 0;

    handle = bio_get_ref(&reply);

    if (handle)
        binder_acquire(bs, handle);

    binder_done(bs, &msg, &reply);

    return handle;
}

int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
    int status;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);
    bio_put_obj(&msg, ptr);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
        return -1;

    status = bio_get_uint32(&reply);

    binder_done(bs, &msg, &reply);

    return status;
}

unsigned token;

int main(int argc, char **argv)
{
    struct binder_state *bs;
    uint32_t svcmgr = BINDER_SERVICE_MANAGER;

    //1打开驱动
    bs = binder_open("/dev/binder", 128*1024);
    if (!bs) {
        fprintf(stderr, "failed to open binder driver\\n");
        return -1;
    }

    int ret;

    //2add server      目标服务  服务名称
    ret = svcmgr_publish(bs, svcmgr, "godv", &token);
    if (!ret) {
        fprintf(stderr, "failed to publish godv service\\n");
        return -1;
    }

    ret = svcmgr_publish(bs, svcmgr, "goda", &token);
    if (!ret) {
        fprintf(stderr, "failed to publish goda service\\n");
    }

    //循环 读数据  解析数据  处理数据  回复
    binder_loop(bs, godv_handler);

    argc--;
    argv++;
    return 0;
}

cmds/servicemanager/godv_server.h

#ifndef _GODV_SERVER_H
#define _GODV_SERVER_H

#define HELLO_SVR_CMD_SAYHELLO 0

#define HELLO_SVR_CMD_SAYHELLO_TO 1

#endif

cmds/servicemanager/godv_client.c

/* Copyright 2008 The Android Open Source Project
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "binder.h"
#include "godv_server.h"

uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
    uint32_t handle;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
        return 0;

    handle = bio_get_ref(&reply);

    if (handle)
        binder_acquire(bs, handle);

    binder_done(bs, &msg, &reply);

    return handle;
}

int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
    int status;
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    bio_put_string16_x(&msg, name);
    bio_put_obj(&msg, ptr);

    if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
        return -1;

    status = bio_get_uint32(&reply);

    binder_done(bs, &msg, &reply);

    return status;
}

    struct binder_state *g_bs;
    uint32_t g_handle;

void sayhello(void)
{
    //构造binder_io
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    //放入参数
      //无
    //调用binder_call
    if (binder_call(g_bs, &msg, &reply, g_handle, HELLO_SVR_CMD_SAYHELLO)){
        fprintf(stderr, "failed to binder_call godv server\\n");
    }

    //用replay读取参数

    //处理完毕
    binder_done(g_bs, &msg, &reply);

}

int sayhello_to(char *name)
{
    //构造binder_io
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    //放入参数
    bio_put_string16_x(&msg, name);
    //调用binder_call
    if (binder_call(g_bs, &msg, &reply, g_handle, HELLO_SVR_CMD_SAYHELLO_TO))
        return 0;
    //用replay读取参数
    int ret;
    ret = bio_get_uint32(&reply);

    //处理完毕
    binder_done(g_bs, &msg, &reply);

    return ret;
}

int main(int argc, char **argv)
{
    struct binder_state *bs;
    uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    uint32_t handle;

    bs = binder_open("/dev/binder", 128*1024);
    if (!bs) {
        fprintf(stderr, "failed to open binder driver\\n");
        return -1;
    }

    g_bs = bs;


    //1 getservice
                               //向servicemanager
                                       //获取名为godv的服务
    handle = svcmgr_lookup(bs, svcmgr, "godv");

    g_handle = handle;

    if(!handle)
    {
        fprintf(stderr, "failed to get godv service\\n");
        return -1;
    }
    //2 发送数据
    /*
       假设程序的名称为prog,
       当只输入prog,则由操作系统传来的参数为:
       argc=1,表示只有一程序名称。
       argc只有一个元素,argv[0]指向输入的程序路径及名称:./prog

       当输入prog para_1,有一个参数,则由操作系统传来的参数为:
       argc=2,表示除了程序名外还有一个参数。
       argv[0]指向输入的程序路径及名称。
       argv[1]指向参数para_1字符串。

       当输入prog para_1 para_2 有2个参数,则由操作系统传来的参数为:

       argc=3,表示除了程序名外还有2个参数。

       argv[0]指向输入的程序路径及名称。

       argv[1]指向参数para_1字符串。

       argv[2]指向参数para_2字符串。*/

    int ret;

    if(argc == 2) {    //输入 ./godv_client xxx
        //sayhello
        sayhello();
    } else if (argc == 3){    //输入 ./godv_client xxx xxx
        //sayhello_to

        ret = sayhello_to(argv[2]);
        fprintf(stderr, "get ret of sayhello_to = %d\\n",ret);
    }

    //释放
    binder_release(bs, handle);
    return 0;
}

cmds/servicemanager/Android.bp

cc_defaults {
    name: "servicemanager_flags",

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
    ],
    product_variables: {
        binder32bit: {
            cflags: ["-DBINDER_IPC_32BIT=1"],
        },
    },

    shared_libs: ["liblog"],
}

cc_binary {
    name: "bctest",
    defaults: ["servicemanager_flags"],
    srcs: [
        "bctest.c",
        "binder.c",
    ],
}

cc_binary {
    name: "servicemanager",
    defaults: ["servicemanager_flags"],
    srcs: [
        "service_manager.c",
        "binder.c",
    ],
    shared_libs: ["libcutils", "libselinux"],
    init_rc: ["servicemanager.rc"],
}

cc_binary {
    name: "vndservicemanager",
    defaults: ["servicemanager_flags"],
    vendor: true,
    srcs: [
        "service_manager.c",
        "binder.c",
    ],
    cflags: [
        "-DVENDORSERVICEMANAGER=1",
    ],
    shared_libs: ["libcutils", "libselinux_vendor"],
    init_rc: ["vndservicemanager.rc"],
}

cc_binary {
    name: "godvserver",
    defaults: ["servicemanager_flags"],
    srcs: [
        "godv_server.c",
        "binder.c",
    ],
}

cc_binary {
    name: "godvclient",
    defaults: ["servicemanager_flags"],
    srcs: [
        "godv_client.c",
        "binder.c",
    ],
}

以上是关于Android Binder(C语言版本例子)的主要内容,如果未能解决你的问题,请参考以下文章

Android Binder(C语言版本)

Android Binder(C++版本例子)

Android C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播

Android——Binder

Android Binder(C++版本)

android binder使用