vc++调用webservice
来源:互联网 发布:excel数据后的空格删掉 编辑:程序博客网 时间:2024/06/06 09:10
正在看着AV(AreCont)SDK的时候,老大突然让我转到soap上,原因是刚进公司的我,第一项任务便是研究ONVIF(so many specifications),当然主要的还是看core specification,这是一个axis,bosch and sony 三大牛x整出来的标准规范,为开发网络视频设备软件开发商提供一个标准规范,但是至今为止仍只是少数公司加入了标准规范的行列,可能是他们不求上进吧 。
在core specification中最主要的还是提到了webservice,兼容RTSP,RTCP, RTP 实现实时流传输,采用vc++实现,所以公司还是考虑通过vc++调用webservice,所以老大便给了我这个任务,先熟悉一下。整了一天,才搞了个差不多,感觉很是纳闷,其实程序看起来很简单,但是细节往往能让人迷糊一大段时间。
其实看了阿瑞得文章后,基本上差不多,当然先装soap toolkit3.0是前提,不过中间还是遇到很多问题的,又通过不断的查阅才得以解决,其中总是发生中断的情况,这个主要是因为webservice得URL没有写正确或者没有搞清URL和Namespace Uri的原因吧。不多说了,还是先看我做的流程吧。
First step: New a Asp.net Web Service Application project.
The following is the content of Service1.asmx.cs:
using System;using System.Linq;using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Xml.Linq;namespace TestWebService{ [SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)] [WebService(Namespace = "http://localhost/WebService/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class Service : System.Web.Services.WebService { public Service() { //CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的 InitializeComponent(); } #region 组件设计器生成的代码 //Web 服务设计器所必需的 private System.ComponentModel.IContainer components = null; /**/ /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { } /**/ /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } base.Dispose(disposing); } #endregion // WEB 服务示例 // HelloWorld() 示例服务返回字符串 Hello World // 若要生成,请取消注释下列行,然后保存并生成项目 // 若要测试此 Web 服务,请按 F5 键 [WebMethod] public int Hello(int strName, int strPwd) { int temp = strName * strPwd; return temp; } [WebMethod] public string HelloWorld(int strName, int strPwd) { return "我是shawn!"; } [WebMethod] public string GetStringName() { return "shawn,rock!!!"; } }}
Then F5 debug mode test the application.
Second step:
New a win32 console application:
New a WSWrapper class:
WSWrapper.h
#ifndef _WS_WRAPPER_H_#define _WS_WRAPPER_H_#import "msxml4.dll"#import "C:/Program Files/Common Files/MSSoap/Binaries/mssoap30.dll" / exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", / "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")#include <string>#include <Windows.h>using namespace MSXML2;using namespace MSSOAPLib30; using std::string;typedef struct{ char * sParamName; char * sParamValue;}WSPARAM;class WSWrapper{public: WSWrapper(); virtual ~WSWrapper(); bool InvokeSoap(string wsURL, string wsNameSpace, string wsMethod, WSPARAM *wsParam, int wsCount, char *sEmsg, char *sRmsg, bool wsXML);private:/* const char *_wsURL; const char * _wsNameSapce; const char *_wsMethodName; */};#endifWSWrapper.cpp#include"WSWrapper.h"#include<cstdlib>#include<cstdio>using namespace std;WSWrapper::WSWrapper(){} WSWrapper::~WSWrapper(){ try { CoUninitialize(); } catch(...) { } } // 参数说明:// wsURL:WEBSERVICE的链接地址// wsNameSpace:在页面中定义的命名空间,一般地使用:http://tempuri.org/// wsMethod:要访问的WEBSERVICE 方法名// wsParam: 要使用的参数,见WSPARAM定义,// wsCount: 参数总数// sEmsg://要返回给调用函数的错误码率信息// sRmsg: //要返回的捃执行结果信息// wsXML:要返回的是XML值还是TEXT// 返回值:// 如果正常执行返回true,中间有问题就返回false;bool WSWrapper::InvokeSoap(string wsURL, string wsNameSpace, string wsMethod, WSPARAM *wsParam, int wsCount, char *sEmsg, char *sRmsg, bool wsXML){ HRESULT hr = CoInitialize(NULL);//初始化com环境 if(FAILED(hr)) { strcpy(sEmsg,"初始化COM失败"); printf("initialized com failed."); return false; } ISoapSerializerPtr Serializer; ISoapReaderPtr Reader; ISoapConnectorPtr Connector; //连接到WebService hr = Connector.CreateInstance(__uuidof(HttpConnector30)); if(FAILED(hr)) { //创建com对象出错,一般是因为没有安装com strcpy(sEmsg,"创建HttpConnector FAILED"); printf("create HttpConnector failed."); return false; } Connector->Property["EndPointURL"] = wsURL.c_str(); hr = Connector->Connect(); if (FAILED(hr)) { strcpy(sEmsg,"连接WEBSERVICE FAILED"); printf("connecting webservice failed."); return false; } Connector->Property["SoapAction"] = (wsNameSpace + wsMethod).c_str(); //开始创建webservice的请求Soap包 Connector->BeginMessage(); hr = Serializer.CreateInstance(__uuidof(SoapSerializer30)); if (FAILED(hr)) { strcpy(sEmsg,"CreateInstance Serializer FAILED"); printf("create instance Serializer failed."); return false; } Serializer->Init(_variant_t((IUnknown*)Connector->InputStream)); Serializer->StartEnvelope("SOAP", "http://schemas.xmlsoap.org/soap/envelope/", ""); Serializer->SoapAttribute("xsi", "", "http://www.w3.org/2001/XMLSchema-instance", "xmlns"); Serializer->SoapAttribute("xsd", "", "http://www.w3.org/2001/XMLSchema", "xmlns"); //Serializer->StartEnvelope("","",""); Serializer->StartBody(L"NONE"); Serializer->StartElement(wsMethod.c_str(), wsNameSpace.c_str(), "NONE", ""); for (int i = 0; i < wsCount; i++) { Serializer->StartElement(wsParam[i].sParamName,wsNameSpace.c_str(),"NONE",""); Serializer->WriteString(wsParam[i].sParamValue); Serializer->EndElement(); } Serializer->EndElement(); Serializer->EndBody(); Serializer->EndEnvelope(); try { Connector->EndMessage(); } catch (...) { strcpy(sEmsg,"提交SOAP消息出错"); printf("提交SOAP消息出错"); return false; } //解析返回的soap包 hr = Reader.CreateInstance(__uuidof(SoapReader30)); if(FAILED(hr)) { strcpy(sEmsg,"CreateInstance READER FAILED"); printf("create instance reader failed."); return false; } Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), ""); if (wsXML) { strcpy(sRmsg,(const char*)Reader->RpcResult->xml); } else strcpy(sRmsg,(const char*)Reader->RpcResult->text); return true;}
The last file is TestApp.cpp:
#include "WSWrapper.h"int main(){ string url = "http://localhost:1451/Service1.asmx"; string uri = "http://localhost/WebService/"; string methodName = "HelloWorld"; WSPARAM *params = new WSPARAM[2]; params[0].sParamName = "strName"; params[0].sParamValue = "3"; params[1].sParamName = "strPwd"; params[1].sParamValue = "4"; char errorMessage[20]; char revMessage[100]; WSWrapper wsWrapper; int wsParaCount = 2; bool retValue = wsWrapper.InvokeSoap(url,uri,methodName,params,wsParaCount,errorMessage,revMessage,false); if (retValue) { printf("%s",revMessage); } getchar(); getchar(); return 0;}
其实我遇到的一个最大的问题就是没有返回值的问题,最终还是不小心找到了解决方案,就是:
Serializer->StartElement("strName", _wsNameSapce.c_str(), "NONE", ""); //Serializer->SoapAttribute("xsi:type", "", "xsd:string", ""); Serializer->WriteString("3"); Serializer->EndElement(); Serializer->StartElement("strPwd",_wsNameSapce.c_str(),"NONE",""); Serializer->WriteString("4"); Serializer->EndElement();
一开始的时候,并没有指定strName和strPwd的namespace,最好是跟method的namespace是一致的,就是_wsNameSapce.c_str()。还有一个就是注意当运行webservice的时候把TestApp.cpp中的url改成运行测试webservice的url路径。当然还遇到了其他很多方面的问题,欢迎有需要的人跟我交流。
- vc++调用webservice
- VC++.NET调用WebService
- VC调用WebService例子
- vc++调用webservice
- VC调用Webservice
- vc++调用webservice
- vc调用webservice
- vc++调用webservice
- VC 调用 webservice
- vc 调用webservice
- 在VC中调用 WebService
- 在VC中调用 WebService
- vc调用webservice获取天气预报
- 在VC中调用 WebService
- c#创建webService, vc++ 调用
- VC通过SOAP调用WebService
- 在VC中调用 WebService
- 在VC中调用WebService
- 二叉树最大路径和
- poj 2828 Buy Tickets
- Poj 2749 & Hdu 1815 Building roads (2-SAT + 二分 建图)
- Mapreduce计算框架涉及的技术(2)-工作机制详解
- Run Loops
- vc++调用webservice
- UVA-10603-Fill(BFS+优先队列)
- 解析Core Services 层
- java金额转中文大写
- 【云计算】云计算定义
- c++智能指针
- kettle 下 从dbms向hive导数据
- centos下vi的用法大全
- MyBatis启动:MapperStatement创建