AllJoyn-跨平台方法调用返回值问题
前面的文章中我们测试的跨平台方法调用的返回值是一个String类型的返回值,实际项目要求我们调用方法的返回值可能是多个,或者是集合、结构这样的自定义类型。AllJoyn是否支持呢?
查看官网:https://allseenalliance.org/framework/documentation/develop/api-guide/core/java,在java核心编程的API指导例我们找到了这样的话:
Beyond simple data types, the AllJoyn framework can handle complex data types such as arrays, maps, and structs. In the case of arrays and maps, the data type can be handled by the AllJoyn code with no special action. However, structs require additional annotation.
就是说AllJoyn框架是支持复杂数据类型的,如arrays和maps还有结构体。arrays和maps的情况AllJoyn源码并不需要特别处理,结构体情况需要特别的注释。
我们同样以java和c++代码的例子来看一下如何实现arrays或者maps的返回值实现。首先看到java中接口方法的定义:
@BusInterface (name = "org.my.interface.name")
public interface MyInterface {
@BusMethod
String cat(String a,String b) throws BusException;
}
假设我们的返回值是String类型的数组,那么接口定义修改为如下:
public interface MyInterface {
@BusMethod
String cat(String a,String b) throws BusException;
@BusMethod
String[] catArray(String a,String b) throws BusException;
}
service上添加catArray的实现代码:
class MyBusObject implements MyInterface,BusObject{
public String cat(String a,String b){
a=a.replace('H','T');
b=b.replace('W','B');
return a+b;
}
public String[] catArray(String a,String b){
String[] temp=new String[4];
temp[0]=a;
temp[1]=b;
temp[2]=a.replace('H','T');
temp[3]=b.replace('W','B');
return temp;
}
}
至此,我们的service上的方法都修改完成了。下一步的工作修改client接口实现和方法调用。client原接口实现如下,增加的代码:
/** Create the interface, report the result to stdout, and return the result status. */
QStatus CreateInterface(void)
{
/* Add org.alljoyn.Bus.method_sample interface */
InterfaceDescription* testIntf = NULL;
QStatus status = g_msgBus->CreateInterface(INTERFACE_NAME, testIntf);
if (status == ER_OK) {
printf("Interface '%s' created.\n", INTERFACE_NAME);
testIntf->AddMethod("cat", "ss", "s", "inStr1,inStr2,outStr", 0);
//tb modify
testIntf->AddMethod("catArray", "ss", "as", "inStr1,inStr2,outStrA", 0);
testIntf->Activate();
} else {
printf("Failed to create interface '%s'.\n", INTERFACE_NAME);
}
return status;
}
client调用方法也作出了调整:
/** Do a method call, report the result to stdout, and return the result status. */
QStatus MakeMethodCall(void)
{
ProxyBusObject remoteObj(*g_msgBus, SERVICE_NAME, SERVICE_PATH, s_sessionId);
const InterfaceDescription* alljoynTestIntf = g_msgBus->GetInterface(INTERFACE_NAME);
assert(alljoynTestIntf);
remoteObj.AddInterface(*alljoynTestIntf);
Message reply(*g_msgBus);
MsgArg inputs[2];
inputs[0].Set("s", "Hello ");
inputs[1].Set("s", "World!");
//tb modify
//QStatus status = remoteObj.MethodCall(INTERFACE_NAME, "cat", inputs, 2, reply, 5000);
QStatus status = remoteObj.MethodCall(INTERFACE_NAME, "catArray", inputs, 2, reply, 5000);
if (ER_OK == status) {
//tb modify
//printf("'%s.%s' (path='%s') returned '%s'.\n", SERVICE_NAME, "cat",
// SERVICE_PATH, reply->GetArg(0)->v_string.str);
printf("%s\n",reply->GetSignature());
const MsgArg* stringArray;
size_t fieldListNumElements;
status = reply->GetArgs("as", &fieldListNumElements, &stringArray);
for (unsigned int i = 0; i < fieldListNumElements; i++) {
char* tempString; stringArray[i].Get("s", &tempString);
printf("%s\n", tempString);
}
} else {
printf("MethodCall on '%s.%s' failed.", SERVICE_NAME, "cat");
}
return status;
}
上面代码部分,首先要去查看两个头文件MsgArg.h和Message.h,里边有关于signature的说明,要知道了signature的类型才能正确解析到reply中的MsgArg消息。
这样我们就完成了String类型的数组返回值的解析。最终效果如下如图所示: