>>快速开始
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;
}