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


>>接口定义,可参考《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。


  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 );


  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 );


//自己添加的个人理解

4.返回结构提数组,必须在结构体中再套一层结构体

typedef struct student_Info{
    int  num;
    char *name;
    char *sail;
    int age;
}student_Info;

typedef struct student_ptr{
    $int snum;
    struct student_Info *studentInfo;
}student_ptr;


int ns__getStudentInfo(struct student_ptr *studentPtr);

int  ns__getStudentInfo(struct soap*soap, struct student_ptr *studentPtr)
{
    studentPtr->snum = 2;
    studentPtr->studentInfo = malloc(2*sizeof(*studentPtr->studentInfo));
    int i = 0;
    for(i=0; i<2; i++)
    {
        (studentPtr->studentInfo[i]).num = i;
        char buf[32] = {0};
        sprintf(buf, "zhou%d", i);
        (studentPtr->studentInfo[i]).name = soap_strdup(soap,buf);
        if((i+1)/2)
            (studentPtr->studentInfo[i]).sail = soap_strdup(soap, "nan");
        else
            (studentPtr->studentInfo[i]).sail = soap_strdup(soap, "nv");
        (studentPtr->studentInfo[i]).age = i;
    }
    return SOAP_OK;
}


>>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("VideoWebservice.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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值