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 C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播