一、gSOAP工具介绍(gsoap\bin\win32)
在该目录下存在2个工具:
wsdl2h.exe及soapcpp2.exe
(1)
wsdl2h.exe: 根据WSDL生成C/C++风格的头文件
使用方法: wsdl2h.exe -o XXX.h
WSDL文件名或URL(末尾加:?wsdl)
参数说明:
-o: 文件名,指定输出头文件
-n: 名空间前缀
代替默认的ns
-c:
产生纯C代码,否则是C++代码
-s:
不要使用STL代码
-t:
文件名,指定type map文件,默认为typemap.dat,建立一个字符转换规则文件wsmap.dat,文件内容为xsd__string = |
std::wstring | wchar_t*
-e
禁止为enum成员加上名空间前缀
(2) soapcpp2.exe: 根据头文件自动生成调用远程
SOAP服务的客户端代码(称为存根:Stub)和提供SOAP服务的框架代码(称为框架:Skeleton),另外它也能从头文件生成WSDL文件。
使用方法: soapcpp2 -x -C
WeatherWeb.h
参数说明:
-C:
仅生成客户端代码
-S: 仅生成服务器端代码
-L:
不要产生soapClientLib.c和soapServerLib.c文件
-c:
产生纯C代码,否则是C++代码(与头文件有关)
-I:
指定import路径(此项是必要的,如果前面为指定-s)
-x:
不要产生XML示例文件
-i:
代表使用Proxy(代理),生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
文件 WebService1.asmx
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld(string kk, string jj, int oo)
{
return "Hello World";
}
}
三、使用gsoap创建WebServices相关C++文件
1. 创建webservices相关的头文件test.h
wsdl2h -o test.h http://localhost:22087/WebService1.asmx?WSDL
2. 根据test.h创建cpp文件
soapcpp2.exe -C test.h -I D:\gsoap_2.8.44\gsoap\import
以上命令执行完成后会生成以下文件:
soapC.cpp
soapClient.cpp
soapClientLib.cpp
soapH.h
soapStub.h
test.h
WebService1Soap.HelloWorld.req.xml
WebService1Soap.HelloWorld.res.xml
WebService1Soap.nsmap
四、示例程序
从gsoap目录下将stdsoap2.cpp、stdsoap2.h文件拷贝到工程目录下:
在stdsoap2.cpp文件中添加#include "WebService1Soap.nsmap" 。
将命令生成的文件soapC.cpp、soapClient.cpp、soapH.h、soapStub.h、WebService1Soap.nsmap文件拷贝到工程目录下。
MFC程序中去掉:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
添加:
#include "soapH.h"
struct soap soap;
soap_init(&soap);
soap.send_timeout = 3;// 设置超时时间,防止死等
soap.recv_timeout = 3; // 设置超时时间
//soap_set_mode(&soap, SOAP_C_UTFSTRING);
setlocale(LC_ALL,"chs");// 解决中文乱码问题
soap_set_mode(&soap,SOAP_C_MBSTRING);
_ns1__HelloWorld HelloWorld;
_ns1__HelloWorldResponse HelloWorldResponse;
std::string jj = "北京";
std::string kk = "天津";
HelloWorld.jj = &jj;
HelloWorld.kk = &kk;
HelloWorld.oo = 23;
CStringList list;
if (SOAP_OK == soap_call___ns1__HelloWorld(&soap, NULL, NULL, &HelloWorld, HelloWorldResponse))
{
std::string* str = HelloWorldResponse.HelloWorldResult;
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
五、gsoap调用WCF程序的WebServices版本问题
修改.nsmap文件内容如下:
{"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://schemas.xmlsoap.org/soap/envelope/", NULL},
{"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://schemas.xmlsoap.org/soap/encoding/", NULL},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL},
{"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL},
替换为:
{"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", NULL, NULL},
{"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", NULL, NULL},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance", NULL, NULL},
{"xsd", "http://www.w3.org/2001/XMLSchema", NULL, NULL},
六、创建代理
wsdl2h -o test.h http://localhost:36931/Service1.svc?wsdl
soapcpp2.exe -C -x -L -i test.h -I D:\工作文件夹\FHTeck\地磁上位机\中间件平台\gsoap_2.8.44\gsoap\import
七、使用
#include "soapH.h"
#include "BasicHttpBinding_USCOREIService1.nsmap"
using namespace std;
#include "soapBasicHttpBinding_USCOREIService1Proxy.h"
setlocale(LC_ALL,"chs");// 中文
BasicHttpBinding_USCOREIService1Proxy ss("http://localhost:36931/Service1.svc",SOAP_C_UTFSTRING);
ss.send_timeout
_ns1__SOAPDeviceState HelloWorld;
_ns1__SOAPDeviceStateResponse HelloWorldResponse;
string id = "1";
string state = "2";
HelloWorld.ReaderId = &id;
HelloWorld.ReaderState = &state;
if (SOAP_OK == ss.SOAPDeviceState(&HelloWorld, HelloWorldResponse))
{
}
ss.destroy();