问题来源:
C++开发一个webservice,然后C#开发客户端,这样就需要C#的客户端访问gsoap的服务端。(大家都知道gsoap是C/C++开发webservice的最佳利器) 为什么不考虑直接用wcf开发webservice?那是考虑到以后有可能要移植到Linux平台。
gsoap实现C#(wpf)客户端调用C++服务器端
首先建立C++服务器端,这里需要使用到gsoap
第一步:自己在桌面建立一个文件夹,命名为add,打开add文件夹,新建txt文档,命名为add.txt,拷贝下面的代码到add.txt,点击保存,然后修改add.txt后缀名为add.h
//gsoap ns service name: add
//gsoap ns service namespace: http://localhost/add.wsdl
//gsoap ns service location: http://localhost
//gsoap ns service executable: add.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:add
int ns__add( int num1, int num2, int* sum );
第二步:从gsoap文件里面拷贝soapcpp2.exe到add文件夹里面,然后打开cmd命令行,输入:soapcpp2.exe add.h会生成许多文件,如图
第三步:新建Win32控制台应用程序,命名为:gsoapApplication_1_S;
添加wsock32.lib引用;
从add文件夹中拷贝如下图所示文件到该项目中,其中黑圈里面的两个项目来自gsoap拷贝:
第四步:修改gsoapApplication_1_S.cpp,其代码如下:
// gsoapApplication_1_S.cpp : 定义控制台应用程序的入口点。
//
#include "add.h"
#include "add.nsmap"
int main(int argc, char* argv[])
{
int m, s;
/* master and slave sockets */
struct soap add_soap;
soap_init(&add_soap);
//soap_set_namespaces(&add_soap, add_namespaces);
m = soap_bind(&add_soap, NULL, 4567, 100);
if (m < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: master socket = %d/n", m);
for ( ; ; )
{
s = soap_accept(&add_soap);
if (s < 0)
{
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, "Socket connection successful: slave socket = %d/n", s);
soap_serve(&add_soap);//该句说明该server的服务
soap_end(&add_soap); }
return 0; }
//server端的实现函数与addmethod.h中声明的函数相同,但是多了一个当前的soap连接的参数
int ns__add(struct soap *add_soap, int num1, int num2, int *sum)
{
*sum = num1 + num2;
return SOAP_OK;
}
第五步:编译成功,打开cmd命令行,输入gsoapApplication_1_S.exe 4567打开主服务,如图
第六步:打开IE浏览器,输入:http://localhost:4567 回车,如图所示,服务器端已经配置成功
配置C#(wpf)客户端,使用到wsdl.exe,在本地搜索一下,没有的话需要在网上下载一个,我是在网上下载的,下载很简单
第一步:拷贝wsdl.exe到add文件夹,打开vs自带的黑屏命令行工具,输入:wsdl /out add.wsdl回车,会生成.cs文件,文件里面包含多线程、代理等信息,如下图
第二步:新建WPF应用程序,命名为gsoapApplication_1_C_WPF,拷贝add.cs,add.wsdl两个文件到该工程中,(主要针对用别人的服务没法修改,亦可这样操作:右键点击C#窗口项目的“引用”选择“添加服务引用”,就会出现一个填写wsdl所在地址的对话框,可以选择是远端webservice服务地址下的wsdl,当然也可以是本地的。我选择的是本地地址,也就是C:\add.wsdl,点击“前往”。就会找到服务。这时下面的名字空间最好写的和当初gsoap建立时指定的命名空间一样。其实不一样也可以,但是在项目中使用的时候用的就是这个新的名字了。)修改add.cs文件代码的”http://localhost/add.cgi“为”http://localhost:4567/add.cgi“,如图所示:
第三步:MainWindow.xaml界面代码如下:
<Window x:Class="gsoapApplication_1_C_WPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<GroupBox Header="Add" HorizontalAlignment="Left" Margin="52,43,0,0" VerticalAlignment="Top" Height="236" Width="412">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<Label Content="number 1:" HorizontalAlignment="Right" VerticalAlignment="Center"/> </Grid>
<Grid Grid.Row="0" Grid.Column="1">
<TextBox Name="num1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" Height="30"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="0">
<Label Content="number 2:" HorizontalAlignment="Right" VerticalAlignment="Center"/> </Grid>
<Grid Grid.Row="1" Grid.Column="1">
<TextBox Name="num2" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" Height="30"/>
</Grid>
<Grid Grid.Row="2" Grid.Column="0">
<Label Content="result----:" HorizontalAlign