您的位置:首页 > 编程语言 > C语言/C++

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

2012-04-01 11:00 671 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: