05.Binder系统:第7课第2节_Binder系统_c++实现_编译测试

该小节,主要是把上小节我们编写的代码,进行修改,然后编译进入系统

IHelloService.h


/* ²Î¿¼: frameworks\av\include\media\IMediaPlayerService.h */

#ifndef ANDROID_IHELLOERVICE_H
#define ANDROID_IHELLOERVICE_H

#include <utils/Errors.h>  // for status_t
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>

#define HELLO_SVR_CMD_SAYHELLO     0
#define HELLO_SVR_CMD_SAYHELLO_TO  1


namespace android {

class IHelloService: public IInterface
{
public:
    DECLARE_META_INTERFACE(HelloService);
	virtual void sayhello(void) = 0;
	virtual int sayhello_to(const char *name) = 0;
};

class BnHelloService: public BnInterface<IHelloService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

	virtual void sayhello(void);
	virtual int sayhello_to(const char *name);

};
}

#endif


BnHelloService.cpp


/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */

#define LOG_TAG "HelloService"

#include "IHelloService.h"


namespace android {

status_t BnHelloService::onTransact( uint32_t code,
                                const Parcel& data,
                                Parcel* reply,
                                uint32_t flags)
{
	/* 解析数据,调用sayhello/sayhello_to */

    switch (code) {
        case HELLO_SVR_CMD_SAYHELLO: {
			sayhello();
            return NO_ERROR;
        } break;
		
        case HELLO_SVR_CMD_SAYHELLO_TO: {

			/* 从data中取出参数 */
			int32_t policy =  data.readInt32();
			String16 name16 = data.readString16();
			String8 name8(name16);

			int cnt = sayhello_to(name8.string());

			/* 把返回值写入reply传回去 */
			reply->writeInt32(cnt);
			
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

void BnHelloService::sayhello(void)
{
	static int cnt = 0;
	ALOGI("say hello : %d\n", cnt++);

}

int BnHelloService::sayhello_to(const char *name)
{
	static int cnt = 0;
	ALOGI("say hello to %s : %d\n", name, cnt++);
	return cnt;
}

}


BpHelloService.cpp


/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */

#include "IHelloService.h"

namespace android {

class BpHelloService: public BpInterface<IHelloService>
{
public:
    BpHelloService(const sp<IBinder>& impl)
        : BpInterface<IHelloService>(impl)
    {
    }

	void sayhello(void)
	{
		/* 构造/发送数据 */

        Parcel data, reply;
        data.writeInt32(0);

        remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);
	}
	
	int sayhello_to(const char *name)
	{
		/* 构造/发送数据 */
        Parcel data, reply;

        data.writeInt32(0);
        data.writeString16(String16(name));

        remote()->transact(HELLO_SVR_CMD_SAYHELLO_TO, data, &reply);

		return reply.readInt32();
	}

};

IMPLEMENT_META_INTERFACE(HelloService, "android.media.IHelloService");

}



test_server.cpp


/* 参考: frameworks\av\media\mediaserver\Main_mediaserver.cpp */

#define LOG_TAG "HelloService"
//#define LOG_NDEBUG 0

#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <utils/Log.h>

#include "IHelloService.h"


using namespace android;

int main(void)
{
	/* addService */

	/* while(1){ read data, 解析数据, 调用服务函数 } */

	/* 打开驱动, mmap */
	sp<ProcessState> proc(ProcessState::self());

	/* 获得BpServiceManager */
	sp<IServiceManager> sm = defaultServiceManager();

	sm->addService(String16("hello"), new BnHelloService());

	/* 循环体 */
	ProcessState::self()->startThreadPool();
	IPCThreadState::self()->joinThreadPool();

	return 0;
}



test_client.cpp



#define LOG_TAG "HelloService"
//#define LOG_NDEBUG 0

#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <utils/Log.h>

#include "IHelloService.h"

using namespace android;

/* ./test_client hello
 * ./test_client hello <name>
 */
int main(int argc, char **argv)
{
	int cnt;
	
	if (argc < 2){
        ALOGI("Usage:\n");
        ALOGI("%s <hello|goodbye>\n", argv[0]);
        ALOGI("%s <hello|goodbye> <name>\n", argv[0]);
        return -1;
	}

	/* getService */
	/* 打开驱动, mmap */
	sp<ProcessState> proc(ProcessState::self());

	/* 获得BpServiceManager */
	sp<IServiceManager> sm = defaultServiceManager();

    sp<IBinder> binder =
        sm->getService(String16("hello"));

	if (binder == 0)
	{
        ALOGI("can't get hello service\n");
		return -1;
	}

	/* service肯定是BpHelloServie指针 */
    sp<IHelloService> service =
        interface_cast<IHelloService>(binder);


	/* 调用Service的函数 */
	if (argc < 3) {
		service->sayhello();
		ALOGI("client call sayhello");
	}
	else {
		cnt = service->sayhello_to(argv[2]);
		ALOGI("client call sayhello_to, cnt = %d", cnt);
	}
	
	return 0;
}

Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	BnHelloService.cpp \
	BpHelloService.cpp \
	test_server.cpp

LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libutils \
	liblog \
	libbinder 


LOCAL_MODULE:= test_server
LOCAL_32_BIT_ONLY := true

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	BpHelloService.cpp \
	test_client.cpp

LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libutils \
	liblog \
	libbinder 


LOCAL_MODULE:= test_client
LOCAL_32_BIT_ONLY := true

include $(BUILD_EXECUTABLE)

在APP_004_Binder_CPP_App文件夹中,编写完成以上文件之后,把APP_004_Binder_CPP_App文件夹拷贝到SDK/frameworks/testing(自己创建)目录下,然后执行mmm命令,烧写到内核

实验现象

待开发板启动之后,执行

test_server & 
logcat HelloService:* *:S & 
test_client  hello

可以看到类似:
01-18 12:33:39.707 1455 1456 I HelloService: say hello : 0
01-18 12:33:39.708 1461 1461 I HelloService: client call sayhello
打印信息,代表完成,也可以再执行:
test_client hello
看到如下打印信息
01-18 12:34:39.877 1455 1456 I HelloService: say hello to 123 : 0
01-18 12:34:39.877 1462 1462 I HelloService: client call sayhello_to, cnt = 1

下小节我们将对该些程序进行详细的分析。

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/89045271