gsoap使用总结

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

>>用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;
     }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[react] 使用React的memo和forwardRef包装的组件为什么提示children类型不对?

[react] 使用React的memo和forwardRef包装的组件为什么提示children类型不对? 过去使用Component、FC等类型定义组件时一般不需要我们定义props里children的类型,因为在上述类型里已经帮你默认加上了 { children?: ReactNode } 的定义。但是types/reac…

2011阿里巴巴程序设计公开赛 / 1002 Fruit Ninja

某神的代码&#xff1a; #include<stdio.h> #define max(x,y) (x)>(y)?(x):(y) #define min(x,y) (x)<(y)?(x):(y) const int inf0x7fffffff;struct node // Fruit {int adv;int x[11],y[11]; }Fruit[11];int Fruit_num,ans;//---- int judge( int x1…

绑定注意事项——数据源的属性

&#xff08;一&#xff09;属性的绑定总结&#xff08;以下属性均指“数据源的属性”&#xff09;&#xff1a; 1&#xff1a;属性的绑定&#xff08;单体属性和集合属性&#xff09;&#xff1a; 若要 将属性值或引用 的变化 通知给UI&#xff0c;则要求属性具有改变通知的功…

[react] 怎样将多个组件嵌入到一个组件中?

[react] 怎样将多个组件嵌入到一个组件中&#xff1f; import A from /* 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

Bash脚本报错:“/bin/bash^M: bad interpreter: No such file or directory”

1、问题 github下载一个源码&#xff0c;运行install脚本时&#xff08;# ./myinstal_cp&#xff09;一直报错“/bin/bash^M: bad interpreter: No such file or directory”&#xff0c;如&#xff1a; -bash: ./myinstall_cp: /bin/bash^M: bad interpreter: No such file …

16、常用shell命令方法

1、shell基本 2、父shell在执行shell命令时&#xff0c;通常是创建子shell&#xff0c;继承父shell环境&#xff0c;执行命令&#xff0c;退出&#xff0c;相关环境销毁&#xff1b;父shell得到子shell的退出状态。 通过命令.或source来使其有当前环境中执行&#xff0c;而不创…

Linux学习之exit函数

From: http://hi.baidu.com/homappy/item/549b37c06865877488ad9e75 若父进程在子进程之前终止了&#xff0c;则子进程的父进程将变为init进程&#xff0c;其PID为1&#xff1b;保证每个进程都有父进程。 Linux学习之"exit函数" 先看下"_exit"和"ex…

为什么要设置环境变量,环境变量有什么用?

比如说你要执行 java 命令&#xff0c;你不设置环境变量path包括你的jdk安装路径&#xff0c;那系统去哪找你的java.exe文件。 如果执行某个命令&#xff0c;系统无法在当前文件夹里找到对应的.exe&#xff0c;那么系统就会去path包含的路径找挨个找看是否能知道对应的.exe&…

CM3计算板RTC闹钟唤醒系统

1、前言 一个周期性控制系统的核心为CM3计算板&#xff0c;在电池供电情况下要求尽可能提高使用时长。由于系统空闲时长较多&#xff0c;因此在考虑低功耗的情况下将系统关机以进一步降低功耗。需要注意的是&#xff0c;系统关机后需要在指定时间唤醒&#xff0c;继续执行相关…

[react] 在React中如果去除生产环境上的sourcemap?

[react] 在React中如果去除生产环境上的sourcemap&#xff1f; GENERATE_SOURCEMAPfalse react-scripts buildIf you use the Create-React-APP 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目…

[相关总结性文章] 写给即将入行的程序员的一封信

本文来自&#xff1a;安卓航班网 首先&#xff0c;欢迎来到程序员的世界。在这个世界上&#xff0c;不是有很多人想创造软件并解决问题。你是一名hacker&#xff0c;属于那些愿意做一些有挑战性的事情的人。  “当你不创造东西时&#xff0c;你只会根据自己的感觉而不是能力去…

火狐浏览器所有的快捷键

From: http://zhidao.baidu.com/question/218604936.html firefox快捷键搜索类&#xff1a;本页查找&#xff1a; CtrlF 再次查找&#xff1a; F3 输入查找链接&#xff1a; 输入查找文本&#xff1a; / 查找&#xff1a; ShiftF3 网页搜索&#xff1a; CtrlK 或 CtrlEfire…

超文本引用href的几种用法

href"要跳转目标链接"; href"#";当前页面不跳转&#xff08;返回顶部&#xff09; href"###";当前页面不跳转&#xff08;同时不回到顶部&#xff09; href"javascript:;";当前页面不跳转&#xff0c;返回空 href"javscript:void…

[react] React的触摸事件有哪几种?

[react] React的触摸事件有哪几种&#xff1f; onTouchCancel onTouchEnd onTouchMove onTouchStart 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

arm-linux-gnueabihf gcc8.3交叉编译工具搭建教程

一、运行环境 1.1 执行机环境 ld GNU ld (GNU Binutils for Raspbian) 2.31.1 ldd ldd (Debian GLIBC 2.28-10rpi1) 2.28 Copyright (C) 2018 Free Software Foundation, Inc. gcc (Raspbian 8.3.0-6rpi1) 8.3.0 Copyright (C) 2018 Free Software Foundation, Inc.…

Md5 Md5实现原理

参考&#xff1a; http://wenku.baidu.com/view/ddb1008271fe910ef12df8df.html转载于:https://www.cnblogs.com/85538649/archive/2011/08/24/2152187.html

Linux tcpdump命令详解

From: http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html 简介 用简单的话来定义tcpdump&#xff0c;就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包…

Win7 64bit系统下未能加载文件或程序集“System.Data.SQLite”的另一解决办法

在http://www.cnblogs.com/downcom/archive/2009/10/26/1590120.html中我曾给出一种解决方法&#xff0c;但这种方法在本地用64位系统开发程序&#xff0c;但服务器却是使用的32位的系统时却是很麻烦的&#xff0c;一直得改来改去的&#xff0c;今天使用另一种解决方法。 1、打…

整理一下网上看到的几个巧妙小电路

1、单按键开关机电路 思路&#xff1a;按下按键后&#xff0c;MCU输出开机信号PG1&#xff0c;关机则检测KEY1的电平&#xff0c;关键是二极管构成“或”的电路。 2、USB和电池供电切换电路 思路&#xff1a;USB有电则断开电池供电回路&#xff0c;用P-MOS管实现 3、快速放电…

[react] 状态管理器解决了什么问题?什么时候用状态管理器?

[react] 状态管理器解决了什么问题&#xff1f;什么时候用状态管理器&#xff1f; 专注 view 层 React 官网是这么简介的。JavaScript library for building user interfaces.专注 view 层 的特点决定了它不是一个全能框架&#xff0c;相比 angular 这种全能框架&#xff0c;R…