转自:https://blog.csdn.net/bytxl/article/details/11627249
生成wsdl文件步骤
头文件如下(注意空格问题)
// ws_interface.h
#ifndef WS_INTERFACE_H
#define WS_INTERFACE_H
// 注意:以下注释是必要的
//gsoap ns service name: ws_interface
//gsoap ns service style: rpc
//gsoap ns service namespace: https://127.0.0.1:4433/cgi-bin/ws_interface.wsdl
//gsoap ns service location: https://127.0.0.1:4433/cgi-bin
//gsoap ns service executable: ws_interface.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:ws_interface
typedef struct ns__AddGroupRequest
{
char *validationCode;
char *name;
char *desc;
} ns__AddGroupRequest;
typedef struct ns__AddGroupResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__AddGroupResponse;
typedef struct ns__DelGroupRequest
{
char *validationCode;
char *name;
} ns__DelGroupRequest;
typedef struct ns__DelGroupResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__DelGroupResponse;
typedef struct ns__OpGroupRequest
{
char *validationCode;
char *name;
int enable; // 0 disable, 1 enable
} ns__OpGroupRequest;
typedef struct ns__OpGroupResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__OpGroupResponse;
typedef struct ns__ModifyGroupRequest
{
char *validationCode;
char *name;
char *newname;
} ns__ModifyGroupRequest;
typedef struct ns__ModifyGroupResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__ModifyGroupResponse;
typedef struct ns__AddUserRequest
{
char *validationCode;
char *name;
char *truename;
char *passwd;
char *groupname; // user belong to group name
} ns__AddUserRequest;
typedef struct ns__AddUserResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__AddUserResponse;
typedef struct ns__DelUserRequest
{
char *validationCode;
char *name;
} ns__DelUserRequest;
typedef struct ns__DelUserResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__DelUserResponse;
typedef struct ns__OpUserRequest
{
char *validationCode;
char *name;
int enable; // 0 disable, 1 enable
} ns__OpUserRequest;
typedef struct ns__OpUserResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__OpUserResponse;
typedef struct ns__ModifyUserRequest
{
char *validationCode;
char *name;
char *newname;
char *truename;
char *passwd;
char *groupname; // user belong to group name
} ns__ModifyUserRequest;
typedef struct ns__ModifyUserResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__ModifyUserResponse;
int ns__AddGroup(
ns__AddGroupRequest *AddGroup,
ns__AddGroupResponse *AddGroupResponse );
int ns__DelGroup(
ns__DelGroupRequest *DelGroupRequest,
ns__DelGroupResponse *DelGroupResponse );
int ns__OpGroup(
ns__OpGroupRequest *OpGroupRequest,
ns__OpGroupResponse *OpGroupResponse );
int ns__ModifyGroup(
ns__ModifyGroupRequest *ModifyGroupRequest,
ns__ModifyGroupResponse *ModifyGroupResponse );
int ns__AddUser(
ns__AddUserRequest *AddUserRequest,
ns__AddUserResponse *AddUserResponse );
int ns__DelUser(
ns__DelUserRequest *DelUserRequest,
ns__DelUserResponse *DelUserResponse );
int ns__OpUser(
ns__OpUserRequest *OpUserRequest,
ns__OpUserResponse *OpUserResponse );
int ns__ModifyUser(
ns__ModifyUserRequest *ModifyUserRequest,
ns__ModifyUserResponse *ModifyUserResponse );
#endif
运行如下命令生成wsdl与源文件:
mkdir ws_interface //生成文件后保存的位置
soapcpp2 -Scd ./ws_interface ./ws_interface.h
关于类型的定义
不能因为某个结构一致,而使用typedef定义别名,这样在生成的wsdl中会有两个同样名字的参数,
而导致wsdl文件出现语法错误
例如,如下的头文件是错误的:
// ws_interface.h
#ifndef WS_INTERFACE_H
#define WS_INTERFACE_H
//gsoap ns service name: ws_interface
//gsoap ns service style: rpc
//gsoap ns service namespace: https://127.0.0.1:4433/cgi-bin/ws_interface.wsdl
//gsoap ns service location: https://127.0.0.1:4433/cgi-bin
//gsoap ns service executable: ws_interface.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:ws_interface
typedef struct ns__CommonResponse
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__CommonResponse;
typedef struct ns__AddGroupRequest
{
char *validationCode;
char *name;
char *desc;
} ns__AddGroupRequest;
typedef struct ns__DelGroupRequest
{
char *validationCode;
char *name;
} ns__DelGroupRequest;
typedef struct ns__CommonResponse ns__AddGroupResponse;
int ns__AddGroup(
ns__AddGroupRequest *AddGroup,
ns__AddGroupResponse *AddGroupResponse );
typedef struct ns__CommonResponse ns__DelGroupResponse;
int ns__DelGroup(
ns__DelGroupRequest *DelGroupRequest,
ns__DelGroupResponse *DelGroupResponse );
#endif
关于gsoap生成的返回值
自定义头文件group.h
typedef struct ns__CommonResponse111111111
{
int returnFlag;
char *msg; // message to descript the return_flag
} ns__CommonResponse2222222222;
typedef struct ns__AddGroupRequest
{
char *validationCode;
char *name;
char *desc;
} ns__AddGroupRequest;
int ns__AddGroup(
ns__AddGroupRequest *AddGroupRequest,
ns__CommonResponse2222222222 *CommonResponse );
/
然后用如下命令生成.c文件:
soapcpp2 -S -c group.h
程序运行时,返回的数据被CommonResponse2222222222包裹:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:ws_account"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:CommonResponse2222222222>
<returnFlag>-460</returnFlag>
<msg>group name is empty</msg>
</ns:CommonResponse2222222222>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
注意:soapcpp2 -S -c group.h命令生成的样例res.xml中数据是被CommonResponse111111111包裹,与实际运行程序后生成的数据不符
具体应用测试代码:
C++:https://download.csdn.net/download/yuchunhai321/10681414
C :https://download.csdn.net/download/yuchunhai321/10708628
设置webservice传输中文为UTF8格式, soap_set_mode(proxy->soap, SOAP_C_UTFSTRING);
C语言用gsoap传递结构型数组 ---转载,未认证
传递一个结构型数组。结构定义如下:
struct JobStatusDetail {
int jobId;
int status;
char cpuTime[10];
char wallTime[10];
}
步骤一、定义gsoap的.h文件
//gsoap ns service name: JobService
//gsoap ns service style: rpc
//gsoap ns service encoding: encoded
//gsoap ns service namespace: http://abc.com/Jobservice.wsdl
//gsoap ns service location: http://abc.com/Jobservice.cgi
//gsoap ns schema namespace: urn:JobService
typedef struct JobStatusDetail {
int jobId;
int status;
char cpuTime[10];
char wallTime[10];
} testType;
typedef testType *xsd__JobStatusDetailPointer;
struct ns__JobStatusPointer {
xsd__JobStatusDetailPointer *__ptr;
int __size;
};
int ns__StructArrayTest(char *cmd, struct ns__JobStatusPointer *structResult);
步骤二、实现服务器端的函数如下,整个gsoap服务器端程序结构可参见gsoap服务器与客户机程序的建立过程
int ns__StructArrayTest(struct soap *soap, char *cmd, struct ns__JobStatusPointer *structResult) {
structResult->__size=2; //数组有两个element
structResult->__ptr = malloc((structResult->__size+1)*sizeof(*structResult->__ptr));
structResult->__ptr[0]=(testType *)malloc(sizeof(testType));
(*structResult->__ptr[0]).jobId=1; //搞了很久,终于明白(*structResult->__ptr[0])里一定存放结构具体内容
(*structResult->__ptr[0]).status=1;
strcpy((*structResult->__ptr[0]).cpuTime,"11:11:11");
strcpy((*structResult->__ptr[0]).wallTime,"22:22:22");
structResult->__ptr[1]=(testType *)malloc(sizeof(testType));
(*structResult->__ptr[1]).jobId=2;
(*structResult->__ptr[1]).status=2;
strcpy((*structResult->__ptr[1]).cpuTime,"33:33:33");
strcpy((*structResult->__ptr[1]).wallTime,"44:44:44");
return SOAP_OK;
}
步骤三、实现客户端程序
#include "soapH.h"
#include "JobService.nsmap"
#include <string.h>
const char server[] = "http://**.**.**:nnnn";
static char Server[]="**.**.**";
int main(int argc, char **argv)
{
struct soap soap;
char buf[1024]="Tell me the job status!";
struct ns__JobStatusPointer result;
if (argc<1)
{
fprintf(stderr, "Usage: jobOptionfile \n");
exit(0);
}
soap_init(&soap);
strcpy(buf, argv[1]);
soap_call_ns__StructArrayTest(&soap, server,"", buf, &result);
if (soap.error) {
soap_print_fault(&soap, stderr);
printf("soap wrong: %d, \n please inform the administrator!\n",soap.error);
exit(1);
}
int i;
for (i=0; i<result.__size; i++)
printf ("jobid: %d jobStatus:%d, cpuTime:%s, wallTime:%s\n",result.__ptr[i]->jobId,result.__ptr[i]->status,result.__ptr[i]->cpuTime, result.__ptr[i]->wallTime);
soap_destroy(&soap);
soap_end(&soap);
return 1;
}
编译完成后,运行客户端程序,在运行结束后,服务器和客户端的当前目录下会有SENT.log和RECV.log两个文件,可以用来查来两端收发消息的内容。
gsoap一次可以传递的信息的大小是有缺省规定的,但可以修改。可查看gsoap手册。