转gsoap使用总结

gsoap使用总结

>>用C实现WebService,gsoap是最好的选择了.
>>快速开始
  1. gsoap官网。遇到问题时,官网往往是最能提供帮助的地方。
     http://gsoap2.sourceforge.net/
  2. 几个值得参考的链接。
     GSoap使用心得: http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html
     GSoap接口定义: http://blog.sina.com.cn/s/blog_5ee9235c0100de3g.html
     
>>测试代码
  我是在linux下用C开发的,那就Makefile入手吧。至于服务端的代码,和客户端的代码,可以参考《GSoap使用心得》,或者是gsoap自带的例子。
     a. 用soapcpp2生产gsoap相关代码: $(GSOAP_BIN)/soapcpp2 -c -x ${WSNAME}.h
     b. 服务端所需的代码: soapC.c soapServer.c stdsoap2.c
     c. 客户端所需的代码: soapC.c soapClient.c stdsoap2.c
     d. 其中stdsoap2.c是从gsoap开发包中复制过来的,他的文件是(a)中命令产生的。
     
-------------分隔符------------------------------------
GSOAP_BIN=/usr/local/gSOAP/bin
WSNAME0=soap
WSNAME=SmsWBS
SERVER_OBJS=$(WSNAME0)C.o $(WSNAME0)Server.o stdsoap2.o    ${WSNAME}server.o
CLIENT_OBJS=$(WSNAME0)C.o $(WSNAME0)Client.o stdsoap2.o    ${WSNAME}client.o
AA_OBJS=$(WSNAME0)C.o $(WSNAME0)Server.o $(WSNAME0)Client.o stdsoap2.o ${WSNAME}server.o ${WSNAME}client.o

INCLUDE=
LIBS=
CC=g++ -g -DWITH_NONAMESPACES

#LIBS=-lz -lc -lncurses -lssl -lcrypto
#CC=g++ -g -DWITH_NONAMESPACES -DWITH_OPENSSL

all:server
all:client

${WSNAME}.wsdl:${WSNAME}.h
    $(GSOAP_BIN)/soapcpp2 -c -x ${WSNAME}.h

$(AA_OBJS):%.o:%.c
    $(CC) -c $? $(INCLUDE)

server:Makefile ${WSNAME}.wsdl  $(SERVER_OBJS)
    $(CC) $(SERVER_OBJS) $(LIBS) -o Smsserver -lpthread

client:Makefile ${WSNAME}.wsdl  $(CLIENT_OBJS)
    $(CC) $(CLIENT_OBJS) $(LIBS) -o Smsclient

clean:
    rm -f *.o *.xml *.a *.wsdl *.nsmap \
    $(WSNAME0)H.h $(WSNAME0)C.c $(WSNAME0)Server.c $(WSNAME0)Client.c \
    $(WSNAME0)Stub.* $(WSNAME)$(WSNAME)Proxy.* $(WSNAME)$(WSNAME)Object.* \
    $(WSNAME0)ServerLib.c $(WSNAME0)ClientLib.c $(WSNAME)server ns.xsd $(WSNAME)test

clear:
    rm -f *.o ns.xsd
-------------分隔符------------------------------------

>>接口定义,可参考《GSoap接口定义》。这里我将给出C#引用这个webserver所对应的接口形式。
  gsoap是根据我们定义好的.h文件,然后用工具产生了我们所需的.c文件。所以我们必须根据gsoap的要求编写.h。
  1. 单个参数的传出:
     int ns__add( int a, int b, int *c );
     需要说明的是,这里的ns__是必须的,必须以开始注释中的ns加两个下划线开始。返回值必须是int。
     但是这里的int并不是接口的返回值,而是gsoap内部的返回值。真正的返回值是int *c。
     
     C#中对应的接口:  int add( int a, int b );  返回值就是上述的int *c参数。
     
  2. 多个参数传出,在接口中必须使用结构体
     typedef char * xsd__string;
     typedef long   xsd__int;
     struct ns__personResponse{
         xsd__int age;
         xsd__string name;
         xsd__string address;
     };
     int ns__person( xsd__string buf_in, struct ns__personResponse * buf_out );
     
     在C#中,并不是我们所声明的这样。而是:int person( string buf_in, out string name, out string address );
     即,结构体中的第一个域会变成返回值,其他的变成一个个的输出参数。
     
  3. 返回结构体。如果要返回结构图,那么必须在结构体中再套一层结构体:
     typedef char * xsd__string;
     typedef long   xsd__int;
     struct ns__person{
         xsd__int age;
         xsd__string name;
         xsd__string address;     
     };
     struct ns__personResponse{
         xsd__int ret;
         struct ns__person person;
     };
     int ns__person( xsd__string buf_in, struct ns__personResponse * buf_out );
     
     那么在C#中,看到的接口是这样的:int person( string buf_in, person对应的结构类 );
     
  4. 接口中的下划线,如果接口中的交易名有下划线,必须这么声明:
     int ns__echo_USCOREreverse( char * buf_in, char ** buf_out );
     
     那么,C#中实际上的接口名就是:string echo_reverse( string buf_in );

>>gsoap中返回字符串
  1. 下面是一个逆转字符串的函数。
     int ns__echo_USCOREreverse( char * buf_in, char ** buf_out );
     int ns__echo_USCOREreverse( struct soap *add_soap, char *buf_in, char **buf_out )
     {
        int i, j, len;
        printf( "ns__interface: in=[%s]\n", buf_in );
    
        len = strlen(buf_in);
        *buf_out = (char*)soap_malloc( add_soap, len+1 );
        for( i=len-1, j=0; i>=0; i--, j++ ){
            (*buf_out)[j] = buf_in[i];
        }
        (*buf_out)[j] = 0;

return 0;
     }
     
     其中调用soap_malloc申请空间,并且将他赋给返回参数buf_out。这个空间会在调用soap_end时被释放。
     
>>gsoap传输中文。我使用utf-8编码格式来支持汉字的传输。
  1. 设置gsoap为utf-8传输数据
     soap_set_mode( &SmsWBS_soap, SOAP_C_UTFSTRING );    //设置编码
     SmsWBS_soap.mode|=SOAP_C_UTFSTRING;
     
  2. 使用下面得函数转换我们的传输内容,即将我们的数据转成UTF-8编码:
     int conv_charset( const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen )
     {
         int convlen = olen;
         iconv_t conv = iconv_open( dest, src );
         if( conv == (iconv_t) -1 )
             return -1;
    
          memset( output, 0, olen );
         if( iconv( conv, &input, &ilen, &output, &olen ) ){
             iconv_close(conv);
             return -1;
         }

iconv_close(conv);
         return convlen-olen;
     }
     例子: conv_charset( "UTF-8", "GBK", "林学任.linxr", strlen("林学任.linxr"),  buf_out->name, 100 );
  
>>webserver发布
  1. 在C#中,可以直接引用一个webserver,但是我们写得webserver如何能用被其引用呢。其实只要实现gsoap的fget回调函数即可:
     SmsWBS_soap.fget = http_get;
  2. http_get函数实现
     int http_get(struct soap * soap)
     { 
         FILE *fd = NULL;
     
         char *s = strchr( soap->path, ‘?‘ );
         if( !s || strcmp( s, "?wsdl" ) ){
             return SOAP_GET_METHOD;
         }
     
         fd = fopen( "SmsWBS.wsdl", "rb" );
         if (!fd){
             return 404;
         }
     
         soap->http_content = "text/xml";
         soap_response(soap, SOAP_FILE);
         for (;;){ 
             size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
             if( !r ){
                 break;
             }
             if( soap_send_raw( soap, soap->tmpbuf, r) ){
                 break; 
             }
         }
     
         fclose(fd);
         soap_end_send(soap);
     
         return SOAP_OK;
     }

时间: 2024-11-14 21:33:05

转gsoap使用总结的相关文章

C/C++利用gsoap库调用WebService

C/C++调用WebService需要用到soap库,一般使用的有gsoap和axis cpp两种实现,这里使用gsoap来调用.gsoap可以在 linxu.windows.mac多种平台上使用. gsoap的主页地址是http://gsoap2.sourceforge.net/ 新建一个WebService: 1 //写一个简单的方法 2 [WebMethod(Description="返回字符串")] 3 public string HelloWorld(string str)

使用gSoap规避和修改ONVIF标准类型结构的解析

ONVIF/gSoap依赖关系及问题 ONVIF是一组服务规范,标准参考 gSoap是一套基于实现SOAP通信接口的工具链 即是,当我们需要访问ONVIF的Web Service或实现对ONVIF部分的支持:基于C/C++开发,则需要借助gSoap生成这之间的交互接口调用的代码. gSoap生成代码 wsdl2h 将服务接口描述转换为soapcpp2的转换规则,生成中间头文件. 通常我们前期会选择实现部分服务标准:因此这期间生成的后续多为修改这次生成中间产物.h,而不会一切重新生成. soapc

gSoap工具wsdl2h及soapcpp2指令汇总

gSoap开发包的下载地址http://sourceforge.net/projects/gsoap2,在bin目录下提供了两个工具: 1:wsdl2h:The gSOAP wsdl2h tool imports one or more WSDLs and XML schemas and generates a gSOAP header le with familiar C/C++ syntax to define the Web service operations and the C/C++

gSoap 中文传输

gSoap C soap_init(soap); soap_set_mode(soap, SOAP_C_UTFCSTRING); 调用 Web Service,使用 UTF-8 格式的中文传递. 非 UTF-8 格式字符,使用 iconv API 转换编码格式.

gsoap

http://blog.csdn.net/zhangxiaonanwin/article/details/6023415 https://github.com/stoneyrh/gSOAP https://www.soapui.org/downloads/soapui.html https://github.com/SmartBear/soapui https://www.genivia.com/downloads.html https://sourceforge.net/projects/gs

Onvif开发之Linux下gsoap的使用及移植

一直以来都是在CSDN上面学习别人的东西,很多次想写点什么但是又无从写起.由于公司项目需要,最近一段时间在研究onvif,在网上找了很多资料,发现资料是非常多,但是很少有比较全的资料,或者资料太多无从下手.我打算从做项目开始,用CSDN博客记录我的项目笔记,同时希望能帮助到需要帮助的人,以感谢这么多年来CSDN上各位高手对我的帮助.onvif的开发从gsoap的移植开始!今天完成了gsoap的移植,生成了代码. 一. 开发环境本人开发环境为:1. 电脑主频2.6G,内存4G:2. 虚拟机:Pro

gSoap实现ONVIF中xsd__anyType到具体结构类的转换

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

纯c gSoap实现WebService

一.系统环境linux操作系统kernel2.4.2,安装gsoap2.6到目录/usr/local/gsoap二.gSOAP的简要使用例子下面是一个简单的例子,实现一个加法运算的WebService,具体功能是cli端输入num1和num2,server端返回一个num1和num2相加的结果sum. 1. 首先,我们需要做的是写一个函数声明文件,来定义接口函数ns__add,文件名字为add.h,内容如下: //gsoap ns service name: add//gsoap ns serv

gsoap开发webservice

gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多.绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库.与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来. gSOAP的编译器能够自动的将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构

gsoap使用总结

gsoap使用总结 >>用C实现WebService,gsoap是最好的选择了.近一个月都在折腾这个,做个总结吧,估计会写得比较长.因为其中碰到了不少问题,但最终都解决调了.>>快速开始  1. gsoap官网.遇到问题时,官网往往是最能提供帮助的地方.     http://gsoap2.sourceforge.net/  2. 几个值得参考的链接.     GSoap使用心得: http://www.cppblog.com/qiujian5628/archive/2008/10