gSoap实现ONVIF中xsd__anyType到具体结构类型的转换
上一篇文章已经粗略计划要讨论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到具体结构类型的转换的更多相关文章
- 【转】java中byte数组与int类型的转换(两种方式)----不错
原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...
- Go语言中其他数据与字符串类型的转换
1 概述 Go语言是强类型语言,因此总会需要将字符串转成需要的类型.比如整型和字符串转换,字符串和布尔型的转换等.本文就介绍如何完成这些转换,以下是Go语言关于字符串转换的整理说明,主要是与切片类型的 ...
- opencv中Mat与IplImage,CVMat类型之间转换
opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...
- java中byte数组与int类型的转换(两种方式)
http://blog.csdn.net/z69183787/article/details/38564219 http://blog.csdn.net/z69183787/article/detai ...
- js中关于string转date类型的转换
var date_up = input.split("-");//input表示string类型(时间例如:2017-11-12 10:07:36.653) var date_do ...
- 第53讲:Scala中结构类型实战详解
今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...
- C#中将结构类型数据存储到二进制文件中方法
以往在vb6,vc6中都有现成的方法将结构类型数据写入和读取到二进制文件中,但是在c#中却没有现成的方法来实现,因此我查阅了一些资料,借鉴了网上一些同学的做法,自己写了个类似的例子来读写结构类型数据到 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Swift面向对象基础(上)——Swift中的类和结构体(上)
学习来自<极客学院> import Foundation //1.定义类和结构体 /* [修饰符]calss 类名{ 零到多个构造器 零到多个属性 零到多个方法 零到多个下标 } 修饰符可 ...
随机推荐
- 跨浏览器读取XML
这里跨浏览器,但是只能读取字符串XML文档,可以通过Ajax方式load一个XML文档,将文件XML转变为字符串 // 跨浏览器返回XML DOM对象 function getXMLDOM(xmlSt ...
- VS2010编译libjpeg
环境:win7旗舰版 x64 VS2010 下载源代码下载地址:http://www.ijg.org/,选择windows format file 解压源代码,修改源代码中jconfig.vc为jco ...
- ubuntu设置WPA2-PSK的wifi热点(AP)——hostapd+dhcpd
在ubuntu 12.04中,默认可以设置的wifi热点是只能用WEP加密,毫无疑问,这样的加密方式,安全性低,现在可以在10几秒的时间内破解,并且只能添加ad-hoc模式的热点,不支持添加AP模式, ...
- Error: rpmdb open failed
yumrpmdb: Thread/process 17132/140266190264064 failed: Thread died in Berkeley DB l ...
- Java 集合框架 LinkedHashSet 和 LinkedHashMap 源码剖析
总体介绍 如果你已看过前面关于HashSet和HashMap,以及TreeSet和TreeMap的讲解,一定能够想到本文将要讲解的LinkedHashSet和LinkedHashMap其实也是一回事. ...
- Bridges painting - SGU 121(构造)
题目大意:有个一无向图,给所有的边染色,如果一个点连接的边超过两个,那么最少要染一个白色和一个黑色,能否给整个图染色?不能输出“No solution”. 分析:引用连接 http://edward- ...
- RichTextBox 右键显示 ContextMenuTrip 分类: C# 2014-10-16 10:43 337人阅读 评论(0) 收藏
说明: (1)命名: RichTextBox -> rtxt1 ContextMenuTrip -> cms1 (2)截图: (3)完整代码: <span style=" ...
- LINQ多条件OR模糊查询
本文章转载:http://www.cnblogs.com/guyun/archive/2012/10/18/2729888.html 需求是这样的,有一张表tbl(Key[int],Value[str ...
- Android bitmap图片处理
一.View转换为Bitmap 在Android中所有的控件都是View的直接子类或者间接子类,通过它们可以组成丰富的UI界面.在窗口显示的时候Android会把这些控件都加载到内存中 ...
- 【2014】【辛星】【php】【秋季】【2】第一个php程序
<span style="font-family:KaiTi_GB2312;font-size:18px;">*******************设置server** ...