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

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

简单试验

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

struct _trt__GetProfile

#soapStub.h

  1. #ifndef SOAP_TYPE__trt__GetProfile
  2. #define SOAP_TYPE__trt__GetProfile (1365)
  3. /* trt:GetProfile */
  4. struct _trt__GetProfile
  5. {
  6. char *ProfileToken; /* required element of type tt:ReferenceToken */
  7. };
  8. #endif

头部概览与FD操作

  1. #include "inc.h"
  2. typedef struct soap *soap_pointer;
  3. #include "soap.nsmap"
  4.  
  5. // anyType
  6. int anyType_ready(void)
  7. {
  8. return open("anyType.xml", O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
  9. }
  10. int FD_set(int* FD, int fd)
  11. {
  12. int ret = *FD; *FD = fd;
  13. return ret;
  14. }

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

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

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

主流程 main()

  1. static xsd__anyType* _trt__GetProfile2anyType(soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any);
  2. static struct _trt__GetProfile*
  3. _trt__GetProfile_from_anyType(soap_pointer soap_, struct _trt__GetProfile* _p, xsd__anyType* _any);
  4.  
  5. int main(int argc, char const *argv[])
  6. {
  7. /* code */
  8. struct soap soap;
  9. soap_pointer soap_ = &soap;
  10. soap_init(soap_);
  11. struct _trt__GetProfile Data = {"Profile0"};
  12. xsd__anyType Dom; soap_default_xsd__anyType(soap_, &Dom);
  13. if (_trt__GetProfile2anyType(soap_, &Data, &Dom))
  14. {
  15. soap_default__trt__GetProfile(soap_, &Data);
  16. if (_trt__GetProfile_from_anyType(soap_, &Data, &Dom))
  17. printf("Data >%s", Data.ProfileToken);
  18. }
  19. soap_end(soap_);soap_done(soap_);
  20. return 0;
  21. }

具体转换实现

  1. xsd__anyType* _trt__GetProfile2anyType( soap_pointer soap_, struct _trt__GetProfile* p_, xsd__anyType* _any )
  2. {
  3. int fd = anyType_ready();
  4. bool b = (fd == -1);
  5. if (b) return NULL;
  6. do {
  7. int* FD = &(soap_->sendfd);
  8. fd = FD_set(FD, fd);
  9. b = (soap_write__trt__GetProfile(soap_, p_) != SOAP_OK);
  10. fd = FD_set(FD, fd);
  11. b = b &&(lseek(fd, 0, SEEK_SET) == -1);
  12. if (b) break;
  13. FD = &(soap_->recvfd);
  14. fd = FD_set(FD, fd);
  15. b = (soap_read_xsd__anyType(soap_, _any) != SOAP_OK);
  16. fd = FD_set(FD, fd);
  17. } while(false);
  18. close(fd);
  19. if (b) return NULL;
  20. return _any;
  21. }
  22. struct _trt__GetProfile* _trt__GetProfile_from_anyType(soap_pointer soap_,
  23. struct _trt__GetProfile* _p, xsd__anyType* _any)
  24. {
  25. int fd = anyType_ready();
  26. bool b = (fd == -1);
  27. if (b) return NULL;
  28. do {
  29. int* FD = &(soap_->sendfd);
  30. fd = FD_set(FD, fd);
  31. b = (soap_write_xsd__anyType(soap_, _any) != SOAP_OK);
  32. fd = FD_set(FD, fd);
  33. b = b &&(lseek(fd, 0, SEEK_SET) == -1);
  34. if (b) break;
  35. FD = &(soap_->recvfd);
  36. fd = FD_set(FD, fd);
  37. b = (soap_read__trt__GetProfile(soap_, _p) != SOAP_OK);
  38. fd = FD_set(FD, fd);
  39. } while(false);
  40. close(fd);
  41. if (b) return NULL;
  42. return _p;
  43. }

参考相关

本次试验启发于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

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

The above can be abbreviated to

  1. soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
  2. 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

  1. #ifndef SOAP_TYPE_xsd__duration
  2. #define SOAP_TYPE_xsd__duration (190)
  3. #endif
  4. SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__duration(struct soap*, LONG64 *);
  5.  
  6. SOAP_FMAC3S const char* SOAP_FMAC4S soap_xsd__duration2s(struct soap*, LONG64);
  7. SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__duration(struct soap*, const char*, int, const LONG64 *, const char*);
  8.  
  9. SOAP_FMAC3S int SOAP_FMAC4S soap_s2xsd__duration(struct soap*, const char*, LONG64 *);
  10. SOAP_FMAC1 LONG64 * SOAP_FMAC2 soap_in_xsd__duration(struct soap*, const char*, LONG64 *, const char*);
  11.  
  12. SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__duration(struct soap*, const LONG64 *, const char*, const char*);
  13.  
  14. #ifndef soap_write_xsd__duration
  15. #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 )
  16. #endif
  17.  
  18. SOAP_FMAC3 LONG64 * SOAP_FMAC4 soap_get_xsd__duration(struct soap*, LONG64 *, const char*, const char*);
  19.  
  20. #ifndef soap_read_xsd__duration
  21. #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 )
  22. #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. 跨浏览器读取XML

    这里跨浏览器,但是只能读取字符串XML文档,可以通过Ajax方式load一个XML文档,将文件XML转变为字符串 // 跨浏览器返回XML DOM对象 function getXMLDOM(xmlSt ...

  2. VS2010编译libjpeg

    环境:win7旗舰版 x64 VS2010 下载源代码下载地址:http://www.ijg.org/,选择windows format file 解压源代码,修改源代码中jconfig.vc为jco ...

  3. ubuntu设置WPA2-PSK的wifi热点(AP)——hostapd+dhcpd

    在ubuntu 12.04中,默认可以设置的wifi热点是只能用WEP加密,毫无疑问,这样的加密方式,安全性低,现在可以在10几秒的时间内破解,并且只能添加ad-hoc模式的热点,不支持添加AP模式, ...

  4. Error: rpmdb open failed

    yumrpmdb: Thread/process 17132/140266190264064 failed: Thread died in Berkeley DB l                  ...

  5. Java 集合框架 LinkedHashSet 和 LinkedHashMap 源码剖析

    总体介绍 如果你已看过前面关于HashSet和HashMap,以及TreeSet和TreeMap的讲解,一定能够想到本文将要讲解的LinkedHashSet和LinkedHashMap其实也是一回事. ...

  6. Bridges painting - SGU 121(构造)

    题目大意:有个一无向图,给所有的边染色,如果一个点连接的边超过两个,那么最少要染一个白色和一个黑色,能否给整个图染色?不能输出“No solution”. 分析:引用连接 http://edward- ...

  7. RichTextBox 右键显示 ContextMenuTrip 分类: C# 2014-10-16 10:43 337人阅读 评论(0) 收藏

    说明: (1)命名: RichTextBox  -> rtxt1 ContextMenuTrip -> cms1 (2)截图: (3)完整代码: <span style=" ...

  8. LINQ多条件OR模糊查询

    本文章转载:http://www.cnblogs.com/guyun/archive/2012/10/18/2729888.html 需求是这样的,有一张表tbl(Key[int],Value[str ...

  9. Android bitmap图片处理

    一.View转换为Bitmap         在Android中所有的控件都是View的直接子类或者间接子类,通过它们可以组成丰富的UI界面.在窗口显示的时候Android会把这些控件都加载到内存中 ...

  10. 【2014】【辛星】【php】【秋季】【2】第一个php程序

    <span style="font-family:KaiTi_GB2312;font-size:18px;">*******************设置server** ...