分类: C/C++
2011-01-10 19:01:22
也就是说远程事件是1对多,是被动接收的,没有返回值。并且A,B,C三者都需要先告诉S对什么事件感兴趣,这样S才知道事件发给谁。远程方法是1对1的,就是主动调用并要取回返回值。远程事件和方法是独立的,可以有也可以没有互相没有关系。
typedef DINT (*Gd_Remote_Method_Function)(void *msg_obj, GD_ID method, GD_TABLE *in_out, void *arg, GD_EXIST *exist); 远程方法的执行函数原型
typedef void (*Gd_Remote_Method_Return_Function)(void *msg_obj, GD_ID method, GD_TABLE *out, void *arg, DINT ret, GD_EXIST *exist); 接收远程方法返回值的回调函数原型
void *GdMessageCreate(char *name, Gd_Remote_Method_Function func, void *arg);创建一个远程消息通讯的对象,提供一个name,这个name是整个系统唯一的,如果已经存在相同名字的会创建不成功。提供一个远程方法的执 行函数,这样其他进程才可以远程执行你的方法,如果你不提供别人调用的远程方法,这个参数为NULL,最后一个参数arg会复制给你的func中的参数 arg.
DINT GdMessageRegisterRemoteEvent(void *msg_obj, char *remote, GD_ID event, Gd_Event_Function func, void *arg);该函数告诉远程的remote,我对你的event事件感兴趣,并且如果以后remote触发了该事件,回调执行我提供的函数func, arg会复制到func中的参数arg。
void GdMessageTriggerRemoteEvent(void *msg_obj, GD_ID event, GD_TABLE *in);触发远程事件,所有对msg_obj的event事件感兴趣的其他进程都会收到该事件调用相应的回调函数。参数in这个GD_TABLE也会原 封不动的传递给其他进程的回调函数。比如上面的例子,当S检测到系统有u盘插入时,就执行GdMessageTriggerRemoteEvent(S, GD_STIRNG_ID(u_hotplug), NULL);
void GdMessageDeleteRemoteEvent(void *msg_obj, char *remote, GD_ID event);告诉remote,我对你的event事件不感兴趣了。
DINT GdMessageRemoteMethod(void *msg_obj, char *remote, GD_ID method, GD_TABLE *in, Gd_Remote_Method_Return_Function func, void *arg);执行remote的远程方法,参数in会原封不动的传递给remote的方法执行函数Gd_Remote_Method_Function. 因为是远程方法,没有阻塞等待远程方法的返回结果. 该函数发包后就立即返回,所以用户还要提供一个Gd_Remote_Method_Return_Function func,在以后收到返回结果时会回调这个函数。
void GdMessageIgnoreRemoteReturn(void *msg_obj, char *remote, GD_ID method);忽略remote的远程方法返回结果。
const char *GdMessageGetRemote(void *msg_obj);在各种回调函数中调用该函数的到此时相应的远程进程的名字。
该进程间通讯对象的设计是p2p的,即每个进程的地位都是一样的,都可以既做client又做server,当然在实际使用中大多是一种身份。下面是一个简单的例子:
client:
void remote_method_return(void *msg_obj, GD_ID method, GD_TABLE *out, void *arg, DINT ret, GD_EXIST *exist)
{
printf("server method2 return %d, the table from remote is\n", ret);
GdTableDump(out);
return;
}
main()
{
void *client;
client = GdMessageCreate(GD_STRING_ID(client), NULL, NULL);
GdMessageRemoteMethod(client, "server", GD_STRING_ID(method1), NULL, NULL, NULL);
GdMessageRemoteMethod(client, "server", GD_STRING_ID(method2), NULL, remote_method_return, NULL);
while(1) GdTaskLoopOnce(0);
}
server:
void remote_method(void *msg_obj, GD_ID method, GD_TABLE *in_out, void *arg, GD_EXIST *exist)
{
if(method == GD_STRING_ID(method1))
printf("server got method1\n");
else if(method == GD_STRING_ID(method2))
printf("server got method2\n");
return;
}
main()
{
void *server;
server = GdMessageCreate(GD_STRING_ID(sever), NULL, NULL);
while(1) GdTaskLoopOnce(0);
}