GSoap简单使用


      公司业务需要,用到Soap同WebService对接。本来想使用MS soap toolkit,但是这东东用到的系统的XML解析库,在不同的windows平台下存在冲突,虽然能规避解决,但觉得不完美,转用gsoap微笑。本文简单的介绍VC++ 2010下使用Gsoap生成客户端程序,以及本人遇到的问题,使用的资源,阅读前还是要了解下soap协议(自己也只是知道点皮毛)。

1、资料
下载地址
http://sourceforge.net/projects/gsoap2/
官网
http://genivia.com/Products/gsoap/index.html
官方学习教程
http://genivia.com/Products/gsoap/documentation.html

2、使用VS2010创建简单WebService
2.1 创建工程
New project --> Visual C# --> ASP.Net Empty Web Application

2.2 添加WebServices
Add New Item --> Web Service

2.3 WebService代码
修改了下原有代码,加法接口
namespace WebApplication_Test
{
    /// <summary>
    /// Summary description for WebService1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class WebService1 : System.Web.Services.WebService
    {
        [WebMethod]
        public double TestAdd(double a, double b)
        {
            return a + b;
        }
    }
}
2.4 运行结果


http://localhost:12676/WebService1.asmx
作为服务器的链接地址

3 使用Gsoap生成代码
这里使用gsoap_2.8.17版本,最新的请到官网中下载。
用到.\gsoap-2.8\gsoap\bin\win32
wsdl2h.exe 根据WebService生成.h文件,其中描述了soap服务器的接口等,可以通过doxygen来获得头文件信息。
cmd窗口运行命令:
wsdl2h.exe -o head.h http://localhost:12676/WebService1.asmx?WSDL
-o 指定需要输出的头文件,默认为当前目录
head.h 为输出的.h文件
http://localhost:12676/WebService1.asmx?WSDL 为服务器地址+?WSDL

soapcpp2.exe 解析头文件,生成相应的源代码,运行:
soapcpp2.exe -C -i -x head.h -I ../../Import
常用命令
-C 仅生成客户端代码
-S 仅生成服务器端代码
-c 产生纯C代码,否则是C++代码(与头文件有关)
-I 指定import路径,导入../../Import(不导入会失败)
-x 不要产生XML示例文件
-i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

生成最终文件如下:

其中xxxProxy.h、xxxProxy.cpp即为客户端类代码
对于应用程序,需要使用到的为
soapC.cpp、soapH.h、soapStub.h、soapWebService1SoapProxy.cpp、soapWebService1SoapProxy.h、WebService1Soap.nsmap
以及 ../../stdsoap2.cpp、../../stdsoap2.h

4 生成客户端程序
4.1 简单的创建MFC对话框程序
4.2 添加以上soap文件
由于MFC默认要求CPP文件包含stdafx.h头文件,针对soapC.cpp、soapWebService1SoapProxy.cpp、stdsoap2.cpp,直接编译会提示
1>soap\soapC.cpp(16): warning C4627: '#include "soapH.h"': skipped when looking for precompiled header use
1>          Add directive to 'StdAfx.h' or rebuild precompiled header
1>soap\soapC.cpp(2119): fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "StdAfx.h"' to your source?
1>  soapWebService1SoapProxy.cpp
1>soap\soapWebService1SoapProxy.cpp(11): warning C4627: '#include "soapWebService1SoapProxy.h"': skipped when looking for precompiled header use
1>          Add directive to 'StdAfx.h' or rebuild precompiled header
1>soap\soapWebService1SoapProxy.cpp(221): fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "StdAfx.h"' to your source?
1>  stdsoap2.cpp
1>soap\stdsoap2.cpp(895): warning C4244: 'return' : conversion from 'std::streamsize' to 'size_t', possible loss of data
可手动修改添加头文件,或者修改编译条件

4.3 调用webService
响应OnOK程序,代码如下
#include "soapWebService1SoapProxy.h"
#include "WebService1Soap.nsmap"
void CTestSoapCPlusPlusDlg::OnBnClickedOk()
{
	// TODO: Add your control notification handler code here
	//CDialogEx::OnOK();
	WebService1SoapProxy mySoap;
	_ns1__TestAdd stuParam;
	stuParam.a = 10.0;
	stuParam.b = 100.0;
	_ns1__TestAddResponse stuResponse;

	//! 调用
	char szSever[] = "http://localhost:12676/WebService1.asmx?wsdl";
	if (SOAP_OK == mySoap.TestAdd(szSever, NULL, &stuParam, &stuResponse))
	{
		CString strMsg;
		strMsg.Format("result:%.2f", stuResponse.TestAddResult);
		MessageBox(strMsg);
	}
	else
	{
		CString strMsg;
		strMsg.Format("result:%s", mySoap.soap_fault_string());
		MessageBox(strMsg);
	}
}
注意包含文件
soapWebService1SoapProxy.h,WebService1Soap.nsmap
其中:
szServer指定服务器,如果不明确指定,则使用默认服务器

OK,大功告成


5 碰到的问题
5.1 nafxcw.lib 同 LIBCMT.lib冲突
1>  TestSoapDlg.cpp
1>nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMT.lib(new.obj)
1>nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMT.lib(delete.obj)
1>nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in libcpmt.lib(newaop.obj)
1>nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) already defined in LIBCMT.lib(delete2.obj)
1>J:\C++\Soap\gSoap\Program\TestSoap\Release\TestSoap.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:06.67
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
原因:
nafxcw是MFC运行链接库libcmt是C运行库,编译器先链接了libcmt,再链接nafxcw,导致符号重复定义,具体参见
http://support.microsoft.com/kb/148652/zh-cn
解决:
将两个库都忽略,再按顺序添加,编译器将根据指定的顺序执行链接
注意:
Debug版本下两个库为 nafxcwd.lib、LIBCMTD.lib
Release版本下两个库为 nafxcw.lib、LIBCMT.lib
不注意可能会出现很坑的错误。。。。


5.2 stdSoapC.cpp 无法解析的外部符号_namespace
原因:
nsmap包含错误,该文件是namespace map,定义了个namespaces变量,在stdSoap.cpp中有

5.3 传输中文时,出现乱码
解决(原因没深入):
初始化WebService1SoapProxy类时,使用构造函数
/// Constructor with engine input+output mode control
WebService1SoapProxy(soap_mode iomode);
设置iomode为
SOAP_C_UTFSTRING

6 相关程序文件
包括websevices、客户端、gsoap文件,见
http://download.csdn.net/detail/otosu/6953421


发布了4 篇原创文章 · 获赞 7 · 访问量 1万+
展开阅读全文

onvif 获取摄像头uri问题

09-26

昨天提了问题,找不到了,重新提问 onvif版本2.8.17 海康摄像头 代码如下: void UserGetUri(struct soap *soap, char *token_name, _tds__GetCapabilitiesResponse *capa_resp) { //获取指定通道的流媒体地址 rtsp://192.168.15.240:554/Streaming/Channels/2?transportmode=unicast int result=0 ; printf("\n\n---------------Getting Uri----------------\n"); _trt__GetStreamUri *trt__GetStreamUri = soap_new__trt__GetStreamUri(soap,-1); _trt__GetStreamUriResponse *trt__GetStreamUriResponse = soap_new__trt__GetStreamUriResponse(soap,-1); trt__GetStreamUri->StreamSetup = soap_new_tt__StreamSetup(soap,-1); trt__GetStreamUri->StreamSetup->Stream = (tt__StreamType)0;//tt__StreamType__RTP_Unicast; trt__GetStreamUri->StreamSetup->Transport = soap_new_tt__Transport(soap,-1); trt__GetStreamUri->StreamSetup->Transport->Protocol =tt__TransportProtocol__RTSP;//(tt__TransportProtocol)0;// tt__TransportProtocol__UDP; //RTSP协议 trt__GetStreamUri->StreamSetup->Transport->Tunnel = 0; trt__GetStreamUri->StreamSetup->__size = 1; trt__GetStreamUri->StreamSetup->__any = NULL; trt__GetStreamUri->StreamSetup->__anyAttribute =NULL; trt__GetStreamUri->ProfileToken = token_name; printf("channel token:%s\n",trt__GetStreamUri->ProfileToken); printf("address:%s\n",capa_resp->Capabilities->Media->XAddr); soap_wsse_add_UsernameTokenDigest(soap,"user", "admin", "qwer1234"); //http://100.100.100.248:80/onvif/device_service //capa_resp->Capabilities->Media->XAddr result = soap_call___trt__GetStreamUri(soap,capa_resp->Capabilities->Media->XAddr, NULL, trt__GetStreamUri, trt__GetStreamUriResponse); if (soap->error) { printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); result = soap->error; return; } else { printf("!!!!NOTE: RTSP Addr Get Done is :%s \n",trt__GetStreamUriResponse->MediaUri->Uri); } } soap_call___trt__GetStreamUri 函数返回2 用wireshark抓包,服务端发来的包信息为 env:sender the xml format error 希望大神帮忙! 问答

boa 与onvif融合,出现网页刷新不出来的情况

05-03

具体情况如下: 代码融合后,去访问设备web的时候,会出现页面刷不出来的情况,多刷新几次就好。但是只要出现了 这种情况,我手动杀掉boa这个进程,再次启动的时候就会出现段错误。此段错误经过定位,最终定位到了 gsoap的框架代码。soap_new()这个函数。小弟不晓得如何去解决这个问题,麻烦各位遇到过的大神支招 在出现此问题时的串口打印信息如下: [01/Jan/1970:00:10:32 +0000] root$boa: server version Boa/0.94.13 [01/Jan/1970:00:10:32 +0000] boa: server built May 3 2017 at 10:14:37. [01/Jan/1970:00:10:32 +0000] boa: starting server pid=531, port 80 /opt/Subscribe.cfg is empty request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 [01/Jan/1970:00:10:35 +0000] malformed request: "" request.c-process_requests()-538: OnvifEN:0 [01/Jan/1970:00:10:36 +0000] request from 192.168.165.100 "(null)" ("(null)"): header read: Connection reset by peer request.c-process_requests()-538: OnvifEN:0 [01/Jan/1970:00:10:36 +0000] request from 192.168.165.100 "(null)" ("(null)"): header read: Connection reset by peer request.c-process_requests()-538: OnvifEN:0 request.c-process_requests()-538: OnvifEN:0 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览