zoukankan      html  css  js  c++  java
  • gsoap 学习 1-如何使用

      新年伊始,想把onvif和gsoap boa这三个东西学习下,并作下笔记,当然为了省时间,我昨天下午看了一个下午的gsaop官网pdf感触良多,也做了小测试,废话少说,一下也有一些是摘自网友博客,大部分和pdf上说的翻译版,所以有好多雷同;

    http://www.cnblogs.com/linxr/archive/2011/10/17/2215285.html

    http://www.cs.fsu.edu/~engelen/soap.html

    http://g.51cto.com/flower454/66952

    http://www.cppblog.com/pansunyou/archive/2013/08/05/137563.html

    http://www.cppblog.com/pansunyou/archive/2013/08/05/137563.html

    http://software.intel.com/zh-cn/blogs/2013/05/09/gsoap实现高性能服务inter

    http://www.cppblog.com/woaidongmao/archive/2008/05/28/51400.html 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] ", 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;
         }
         
        

  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/3551608.html
Copyright © 2011-2022 走看看