上一篇文章已经粗略计划要讨论gsoap关于序列化/解析编程。

本文则阐述一下关于gsoap生成代码的一些重要特征方法及使用。如题,下我们从ONVIF生成的C码中,挑选简单的一个类型来试验一下与xsd__anyType之间的转换。这个试验如此重要,主要是因为,在之前我真的拿生成代码的相关结构的的一些__any字段没有办法。虽依据ONVIF文档,以及实际交互观测的XML结构中可知明明是已知的标准结构,却无奈生成被解析成any字段,主要是可能这部分字段可由厂商决定填充哪些扩展意义的结构。

简单试验

本次试验选_trt__GetProfile结构作转换例程,主要理由是这个结构实在简单,只含有一个字段;书写初始化简单。

struct _trt__GetProfile

#soapStub.h

#ifndef SOAP_TYPE__trt__GetProfile
#define SOAP_TYPE__trt__GetProfile (1365)
/* trt:GetProfile */
struct _trt__GetProfile
{
char *ProfileToken; /* required element of type tt:ReferenceToken */
};
#endif

头部概览与FD操作

#include "inc.h"
typedef struct soap *soap_pointer;
#include "soap.nsmap" // anyType
int anyType_ready(void)
{
return open("anyType.xml", O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
}
int FD_set(int* FD, int fd)
{
int ret = *FD; *FD = fd;
return ret;
}

注:inc.h是自组织的部分所需头依赖;

后面包含了soap.nsmap文件,你懂的,里面解开可以可以依次了解清楚包含与依赖关系;

soap.nsmap < soapH.h < soapStub.h < stdsoap2.h

主流程 main()

static xsd__anyType* _trt__GetProfile2anyType(soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any);
static struct _trt__GetProfile*
_trt__GetProfile_from_anyType(soap_pointer soap_, struct _trt__GetProfile* _p, xsd__anyType* _any); int main(int argc, char const *argv[])
{
/* code */
struct soap soap;
soap_pointer soap_ = &soap;
soap_init(soap_);
struct _trt__GetProfile Data = {"Profile0"};
xsd__anyType Dom; soap_default_xsd__anyType(soap_, &Dom);
if (_trt__GetProfile2anyType(soap_, &Data, &Dom))
{
soap_default__trt__GetProfile(soap_, &Data);
if (_trt__GetProfile_from_anyType(soap_, &Data, &Dom))
printf("Data >%s", Data.ProfileToken);
}
soap_end(soap_);soap_done(soap_);
return 0;
}

具体转换实现

xsd__anyType* _trt__GetProfile2anyType( soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any )
{
int fd = anyType_ready();
bool b = (fd == -1);
if (b) return NULL;
do {
int* FD = &(soap_->sendfd);
fd = FD_set(FD, fd);
b = (soap_write__trt__GetProfile(soap_, p_) != SOAP_OK);
fd = FD_set(FD, fd);
b = b &&(lseek(fd, 0, SEEK_SET) == -1);
if (b) break;
FD = &(soap_->recvfd);
fd = FD_set(FD, fd);
b = (soap_read_xsd__anyType(soap_, _any) != SOAP_OK);
fd = FD_set(FD, fd);
} while(false);
close(fd);
if (b) return NULL;
return _any;
}
struct _trt__GetProfile* _trt__GetProfile_from_anyType(soap_pointer soap_,
struct _trt__GetProfile* _p, xsd__anyType* _any)
{
int fd = anyType_ready();
bool b = (fd == -1);
if (b) return NULL;
do {
int* FD = &(soap_->sendfd);
fd = FD_set(FD, fd);
b = (soap_write_xsd__anyType(soap_, _any) != SOAP_OK);
fd = FD_set(FD, fd);
b = b &&(lseek(fd, 0, SEEK_SET) == -1);
if (b) break;
FD = &(soap_->recvfd);
fd = FD_set(FD, fd);
b = (soap_read__trt__GetProfile(soap_, _p) != SOAP_OK);
fd = FD_set(FD, fd);
} while(false);
close(fd);
if (b) return NULL;
return _p;
}

参考相关

本次试验启发于gsoap指南

gSOAP 2.8.11 User Guide

7.5.3 Serializing C/C++ Data to XML

You can assign an output stream to soap.os or a le descriptor to soap.sendfd. For example

soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
soap_serialize_PointerTons_Person(&soap, &p);
soap_begin_send(&soap);
soap_put_PointerTons_Person(&soap, &p, "ns:element-name", "ns:type-name");
soap_end_send(&soap);

The above can be abbreviated to

soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
soap_write_PointerTons_Person(&soap, &p);

gSoap生成代码的重要使用特征

生成清单

  • soapStub.h
  • soapClient.c
  • soapH.h
  • soapC.c
  • soap.nsmap

这是客户端的生成简单,soapClient.c 是soapStub.h的实现, soapC.c是soapH.h的实现,soap.nsmap是定义全局编译所需的xmlns集合namespaces[];

我们主要通过调用soapStub.h声明的方法来完成Service的访问,其中封装了交互过程;所有结构都定义在soapStub.h中有声明;

当然soapH.h则对应每一个结构都生成了相应的序列化/解析的方法,以及一些读写宏。

soapStub.h

所有交互命令的调用及结构声明;

soapH.h

#ifndef SOAP_TYPE_xsd__duration
#define SOAP_TYPE_xsd__duration (190)
#endif
SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__duration(struct soap*, LONG64 *); SOAP_FMAC3S const char* SOAP_FMAC4S soap_xsd__duration2s(struct soap*, LONG64);
SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__duration(struct soap*, const char*, int, const LONG64 *, const char*); SOAP_FMAC3S int SOAP_FMAC4S soap_s2xsd__duration(struct soap*, const char*, LONG64 *);
SOAP_FMAC1 LONG64 * SOAP_FMAC2 soap_in_xsd__duration(struct soap*, const char*, LONG64 *, const char*); SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__duration(struct soap*, const LONG64 *, const char*, const char*); #ifndef soap_write_xsd__duration
#define soap_write_xsd__duration(soap, data) ( soap_serialize_xsd__duration(soap, data), soap_begin_send(soap) || soap_put_xsd__duration(soap, data, "xsd:duration", NULL) || soap_end_send(soap), soap->error )
#endif SOAP_FMAC3 LONG64 * SOAP_FMAC4 soap_get_xsd__duration(struct soap*, LONG64 *, const char*, const char*); #ifndef soap_read_xsd__duration
#define soap_read_xsd__duration(soap, data) ( soap_begin_recv(soap) || !soap_get_xsd__duration(soap, data, NULL, NULL) || soap_end_recv(soap), soap->error )
#endif

我们能见到大量类似这样规则的定义,每个方法的前置宏声明是有区别意义的。

SOAP_FMAC3S 这是序列化成字符串的方法修饰;这类方法主要是一类简单的基本类型到字符串的序列化转换, 比如ONVIF中有定义许多的枚举;

具体这么多修饰宏的意义可以参照stdsoap2.h中描述,在VC环境下使用助手的outline功夫查看文件代码结构是相当直观的。

另外我们还看见每一种类型都定义了soap_read/write_***的函式宏,本文试验主要就是通过这类读写来实现不同实现结构的转换的。

标准化

总之,为了工作简洁高效,日后可读可维护,我们尽量使用标准化的调用方式,而不走偏方,这才是本文针对各编程界提倡的建议。

gSoap实现ONVIF中xsd__anyType到具体结构类型的转换的更多相关文章

  1. 【转】java中byte数组与int类型的转换(两种方式)----不错

    原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...

  2. Go语言中其他数据与字符串类型的转换

    1 概述 Go语言是强类型语言,因此总会需要将字符串转成需要的类型.比如整型和字符串转换,字符串和布尔型的转换等.本文就介绍如何完成这些转换,以下是Go语言关于字符串转换的整理说明,主要是与切片类型的 ...

  3. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  4. java中byte数组与int类型的转换(两种方式)

    http://blog.csdn.net/z69183787/article/details/38564219 http://blog.csdn.net/z69183787/article/detai ...

  5. js中关于string转date类型的转换

    var date_up = input.split("-");//input表示string类型(时间例如:2017-11-12 10:07:36.653) var date_do ...

  6. 第53讲:Scala中结构类型实战详解

    今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...

  7. C#中将结构类型数据存储到二进制文件中方法

    以往在vb6,vc6中都有现成的方法将结构类型数据写入和读取到二进制文件中,但是在c#中却没有现成的方法来实现,因此我查阅了一些资料,借鉴了网上一些同学的做法,自己写了个类似的例子来读写结构类型数据到 ...

  8. Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. Swift面向对象基础(上)——Swift中的类和结构体(上)

    学习来自<极客学院> import Foundation //1.定义类和结构体 /* [修饰符]calss 类名{ 零到多个构造器 零到多个属性 零到多个方法 零到多个下标 } 修饰符可 ...

随机推荐

  1. 多台Mac电脑使用一个apple开发者账号

    直接从已安装好的机器上导出私有密钥的,具体方法如下: Xcode的organizer的IPHONE DEVELOPMENT --->Developer Profile里自带的Export和Imp ...

  2. unity3d Hair real time rendering 真实头发实时渲染

    先放上效果 惊现塞拉酱 算法是Weta Digital根据siggraph2003的论文加以改进,改进之前使用的是Kajiya and Kay’s 模型,它能量不守恒,也就是说不是基于物理的,不准确 ...

  3. senrty 配置Email

    测试页面在这里      右上角头像->管理->邮件 配置如下:(注意一点:465是SSL的 587是TLS的) 其他django email 1.3 文献在这里  现在都1.8了貌似 如 ...

  4. cocos2d的ARC开启

    ARC,官方解释是Automatic Reference Counting,是Apple公司从iOS5开始为开发者新添加的一个功能. 相信很多写移动开发,可能不只是移动开发的人都深有体会,创建一个对象 ...

  5. [转载]JVM性能调优--JVM参数配置

    http://www.cnblogs.com/chen77716/archive/2010/06/26/2130807.html

  6. 关于Cookie的有关内容

    1.首先谈谈http协议与状态保持. Http协议本身是无状态的,这与http协议本来的目的是相符的,客户端只需要简单的向服务器发出请求操作,然后服务器对请求作出响应.无论客户端还是服务器都没有必要记 ...

  7. intelij idea

    tip of day关闭后可以在左上角的help中找到

  8. HTTPClient实现java自动登录人人网

    参考网址: https://passport.csdn.net/account/login  http://www.iteye.com/topic/638206 httpClient http://b ...

  9. javascript正则表达式简述

    compile 编译或改变字符串,参数跟new RegExp相同 var patt = /man/g; var str = "man and woman"; str.replace ...

  10. 自己在安装centos 系统时, 是使用英文安装 成功,现在系统语言为英语,如何设置为中文?

    作为一个linux菜鸟,遇到的问题可谓真多,在虚拟机VMware上安装好centos系统后,心里甚喜,也连上网络了. 一.遇到的问题 but,火狐浏览器浏览网页出现乱码,也不知道怎么解决?所有的中文都 ...