soap: 非托管c++ 客户端的开发(gsoap)

webservice的服务器是c#写的,现在要用c++访问此webservice.有以下方法:

1,托管c++,缺点猜想,部署项目的时候需要包含.net库,讨厌这种拖泥带水的。

2,用c#访问webservice,重新包装一个接口,生成dll, 供c++使用;缺点,还是需要公共语言运行库支持,也即托管c++

3, 用gsoap

 

开发步骤:

1,安装gsoap win32版本。官网是http://gsoap2.sourceforge.net/

2,利用gsoap的bin目录下的两个可执行文件+webservice的wsdl生成一些文,c++直接调用就okay了。

有两种方法:利用soap,利用代理类

我这里用的soap。

 

wsdl2h常用选项

  • -o 文件名,指定输出头文件
  • -n 名空间前缀 代替默认的ns
  • -c 产生纯C代码,否则是C++代码
  • -s 不要使用STL代码
  • -t 文件名,指定type map文件,默认为typemap.dat
  • -e 禁止为enum成员加上名空间前缀

soapcpp2.exe 的使用:

  • -C 仅生成客户端代码
  • -S 仅生成服务器端代码
  • -L 不要产生soapClientLib.c和soapServerLib.c文件
  • -c 产生纯C代码,否则是C++代码(与头文件有关)
  • -I 指定import路径(见上文)
  • -x 不要产生XML示例文件
  • -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

wsdl2h -c -o NxService.h http://192.168.1.104/SendService/SendMessageService.svc?wsdl
soapcpp2 -c -C NxService.h

3,新建项目win32 console。


#include <WinSock2.h>
#pragma comment(lib, "wsock32.lib")
#include "utility.h"

#include "soapH.h"
#include <string>
using namespace std;
int main()
{
 struct soap clientSoap;
 soap_init(&clientSoap);

 soap_set_mode(&clientSoap, SOAP_C_UTFSTRING);

 _ns1__SendMsgSvc request;
 _ns1__SendMsgSvcResponse response;

 //request
 xsd__boolean bIsLimiteRtxMsgLen=xsd__boolean__true_;
 entity.IsLimitRtxMsgLen = &bIsLimiteRtxMsgLen;

 //response
 xsd__boolean SendMsgSvcResult;
 response.SendMsgSvcResult=&SendMsgSvcResult;

 int bret=soap_call___ns1__SendMsgSvc(&clientSoap, NULL, NULL, &request, &response);
 if(bret!=SOAP_OK)
 {
  //err
  soap_print_fault(&clientSoap, stderr);
 }

 return 0;
}

//不直接用BasicHttpBinding_USCOREISendMessageService.nsmap, 因为服务器wsdl文件生成的soap1.2,用gsoap生成1.2,发送的http的contenttype不支持。
//手动修改namespace, 生成soap1.1.
  struct Namespace namespaces[] =
 {
  {"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},
 
  
  //{"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope", NULL},
  //{"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://www.w3.org/2003/05/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},
  
  {"ns4", "http://schemas.datacontract.org/2004/07/SnailGame.Toolkits.MessageSendService", NULL, NULL},
  {"ns3", "http://schemas.microsoft.com/2003/10/Serialization/", NULL, NULL},
  {"ns1", "http://tempuri.org/", NULL, NULL},
  {NULL, NULL, NULL, NULL}
 };

 

 

总结:刚开始用老是返回错误415, 直接include的nsmap的命名空间。错误是content type错误。花了一天时间,寻找gsoap 415的错误,没找到。

后来看了下soap协议,基于http协议的,用截包工具截获一个http/xml包,一看, content type错误。服务器wsdl文件生成的soap1.2, 而服务器只支持soap1.1, 把命名空间改了下就好了。

还有中文的话,先转成utf8格式的。

综上,用别人的库之前,先了解基本的协议。gsoap先了解soap协议,libcurl先了解ftp协议。磨刀不误砍柴工。

 

服务端客户端soap协议不统一:http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/1ff173ee-c371-45b1-986b-fbb67ea94de8/

soap: http://www.w3school.com.cn/soap/soap_httpbinding.asp

你可能感兴趣的:(C++,webservice,服务器,null,SOAP,NameSpaces)