日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C++、C#写的WebService相互调用

發布時間:2025/3/21 C# 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++、C#写的WebService相互调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先感謝永和兄提供C++的WebService服務器端及客戶端,并且陪我一起熬夜;然后是火石和我做接口的兄弟,雖然都不知道你叫什么,如果沒有你的合作,東西也沒那么快完成。

一、由于公司運營火石的《西游Q記》,火石采用的是C++作為開發語言,Unix平臺,而我們一直使用Windows操作平臺,.NET快速開發。我們之間需要數據的通訊,所以需要利用WebService實現跨平臺的數據通訊。盡管WebService是跨平臺的,但是實現起來卻并不容易。

二、用C#實現WebService是相當簡單的事情,我們只要創建一個Web服務程序,在方法名上面加上[WebMethod],部署到IIS上,就能像訪問Web站點一樣訪問WebService。用C#編寫客戶端時,只需要將WebService添加到引用,就能像調用本地方法一樣去調用WebService。像這樣的例子也比比皆是,在這就不多講。

三、用C++實現WebService,一般會用到gsoap,具體方法見:http://www.cppblog.com/qiujian5628/archive/2008/06/19/54019.html

四、當做完了這些之后,并不代表WebService就能相互通訊了,現在我簡單列舉一下問題:

1、C#提供的WebService的URL一般形如:http://localhost/WebService.asmx,但是,C++能提供的只能是:http://localhost/。C++做客戶端的時候調用沒有問題,但是當C#做客戶端的時候,引用C++提供的RUL時,會提示沒用執行方法(HTTPGET method notimplemented)。做C#開發的大部分會認為C++方提供的不是WebService,或者說提供的WebService根本就不全,都不帶.asmx文件。做C++開發的會認為他傳輸的數據符合soap協議,靠http傳輸數據,他就是WebService。

2、當我們解決了第一步后,緊接著會發現另外一個問題。當我們需要傳輸自定義數據類型時(在C++中稱結構體,在C#中稱實體),從C++返回的信息中,C#無法構建出實體類。

3、當傳輸的信息中帶有中文字符時,亂碼滿天飛。

五、為了解決這些問題,我們先簡單了解一下WebService。

Web?Service互操作協議棧:

<A>、服務發現?(UDDI)

<B>、服務描述(WSDL)

<C>、服務調用(SOAP)

<D>、消息編碼?(XML)

<E>、傳輸網絡層(HTTP,?TCP/IP)

其中WSDL描述WebService都有什么方法、方法有什么參數,什么返回值等。SOAP(簡單對象訪問協議(Simple Object AccessProtocol)是一種輕量的、簡單的、基于XML的協議。傳輸的數據就需要遵循這個協議。我比較簡單得認為傳輸的數據需要遵循這種格式。

借用微軟的這個圖描述下WebService的調用過程:

六、開始解決問題。作為.NET開發人員,我們根本就接觸不到底層的東西,全被封裝了。

C++做的確實是WebService,只是他們需要給提供一個描述文檔,即.WSDL文件。使用.NET提供的wsdl.exe工具,使用命令:wsdl/o: c:\webservice.csc:\webservice.wsdl。通過webservice.wsdl文檔,生成代理類,將代理類寫入webservice.cs文件中。我們拷貝這個cs文件到項目中,將URL指向

http://localhost/,就能像以往那樣使用WebService了。

當出現無法傳遞復雜類型數據時,是因為使用gsoap生成的wsdl文件與.Net中生成的wsdl文件不一樣。具體代碼如下:

<!-- operation responseelement -->
? <elementname="result">
??<complexType>
???<sequence>
????<element name="a" type="xsd:int" minOccurs="1"maxOccurs="1"/>
????<element name="b" type="xsd:int" minOccurs="1"maxOccurs="1"/>
???</sequence>
??</complexType>
? </element>

以上為gsoap生成的。返回實體result,實體有兩個屬性:a,b。

<s:elementname="TestResponse">
????<s:complexType>
?????<s:sequence>
??????<s:elementminOccurs="0" maxOccurs="1" name="TestResult" type="tns:result"/>
?????</s:sequence>
????</s:complexType>
???</s:element>
???<s:complexTypename="result">
????<s:sequence>
?????<s:elementminOccurs="1" maxOccurs="1" name="a" type="s:int"/>
?????<s:elementminOccurs="1" maxOccurs="1" name="b" type="s:int"/>
????</s:sequence>
???</s:complexType>

以上是.NET生成的。

在下面的文件中,多出

<s:elementname="TestResponse">
????<s:complexType>
?????<s:sequence>
??????<s:elementminOccurs="0" maxOccurs="1" name="TestResult" type="tns:result"/>
?????</s:sequence>
????</s:complexType>
???</s:element>
這個便是.NET中用來構造實體的。當我們出現情況4.2時,gsoap中盡量使用.NET生成的wsdl文檔,生成.h文件,以避免C++中的結構無法在C#中轉換成實體。

第三個問題,我們是通過將中文轉換成16進制后傳輸過來,然后再轉換成中文。下面提供C#轉換的代碼:

///<summary>
???????/// 從16進制轉換成漢字
???????/// </summary>
???????/// <paramname="hex"></param>
???????///<returns></returns>
???????public static string GetChsFromHex(string hex)
???????{
???????????if (hex == null)
???????????????throw new ArgumentNullException("hex");
???????????if (hex.Length % 2 != 0)
???????????{
???????????????hex += "20";//空格
???????????????//throw new ArgumentException("hex is not a valid number!","hex");
???????????}
???????????// 需要將 hex 轉換成 byte 數組。
???????????byte[] bytes = new byte[hex.Length / 2];

for (int i = 0; i <bytes.Length; i++)
???????????{
???????????????try
???????????????{
???????????????????// 每兩個字符是一個 byte。
???????????????????bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
???????????????????????System.Globalization.NumberStyles.HexNumber);
???????????????}
???????????????catch
???????????????{
???????????????????// Rethrow an exception with custom message.
???????????????????throw new ArgumentException("hex is not a valid hex number!","hex");
???????????????}
???????????}

// 獲得 GB2312,Chinese Simplified。
???????????System.Text.Encoding chs =System.Text.Encoding.GetEncoding("gb2312");


???????????return chs.GetString(bytes);
???????}

///<summary>
???????/// 從漢字轉換到16進制
???????/// </summary>
???????/// <paramname="s"></param>
???????///<returns></returns>
???????public static string GetHexFromChs(string s)
???????{
???????????if ((s.Length % 2) != 0)
???????????{
???????????????s += " ";//空格
???????????????//throw new ArgumentException("s is not valid chinesestring!");
???????????}

System.Text.Encoding chs =System.Text.Encoding.GetEncoding("gb2312");

byte[] bytes = chs.GetBytes(s);

string str = "";

for (int i = 0; i <bytes.Length; i++)
???????????{
???????????????str += string.Format("{0:X}", bytes[i]);
???????????}

return str;
???????}

注:以上來轉換代碼源于網絡,C++中轉換的代碼也可以在網上找到。

三大難題到此結束,其實在整個過程中還有個最大的難題,那就是人與人的交流。因為一方使用C++,一方使用C#,語言不同,各自想問題的方式也不一樣,所以需要相互理解,相互站在對方的角度想問題。多交流、多溝通才是解決問題之道。請不要抱怨C#弱智,也請不要怪C++繁瑣,語言既然存在則有他的價值。

===========================================2012-07-19補=================================

?

typedef char* String;


1.函數聲明如:

class Result

{

public:

Int ErrorCode;

String Description;

};

int ns1__Register(String Account,Result &RegisterResult);//1.創建帳號

ns1__ webservice的名字空間


2.數組聲明例如:

class Group

{

public:

Int ID;

Int Version;

String Name;

Int State;

String TestIP;

};

class LoginServer

{

public:

String IP;

Int Port;

};

class ArrayOffGroup

{

public:

Group *__ptr;

int __size;

};

class ArrayOffLoginServer

{

public:

LoginServer *__ptr;

int __size;

};


class ResultGetGameGroupList

{

public:

Int ErrorCode;

String Description;

ArrayOffGroup Groups;

ArrayOffLoginServer LoginServers;

};

int ns1__GetGameGroupList(void *_,ResultGetGameGroupList&GetGameGroupListResult);//2.獲取當前啟動的服務器組及服務器壓力


3.用gSoap工具從*.h生成C++代碼及*.wsdl文件

soapcpp2.exe *.h生成WebService的C++代碼

注:這里生成的*.wsdl無法用VS的wsdl工具直接生成.net的代理類,需要手動打開*.wsdl把里面的String改為.net認識的string即可.無法直接把char*typedef 成string 這樣的話會使生成的c++代碼無法編譯通過


4.用gSoap工具從*.wsdl生成C++代碼

(1).wsdl2h.exe *.wsdl生成 *.h 文件

(2).soapcpp2.exe*.h生成Webservice的C++代碼

?

5.用Vs的wsdl工具生成.net代理類命令

wsdl /out:C:/myProxyClass.cs?*.wsdl


附錄1.

php調用gSoap的WebService的代碼示例:

<?php

echo "start";

header ( "Content-Type: text/html;charset=utf-8" );

$client = new SoapClient ();

try

{ ?

$params = array('Account'=> 'testtest', 'Password' =>'12341234', 'IP' => '127.0.0.1', 'IsAdult'=> 1, 'Presentee' => 1);

$result =$client->__soapCall("Register"

, array( 'parameters' =>$params)

, array('location' =>'http://url:81', 'uri' =>'ns1'));?

echo ($result);

}

catch(SoapFault $fault)

{

echo($fault->faultstring);

}

?>


總結

以上是生活随笔為你收集整理的C++、C#写的WebService相互调用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。