gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。
gSOAP的编译器能够自动的将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构,反之亦然。这样,只用一组简单的API就将用户从SOAP细节实现工作中解脱了出来,可以专注与应用程序逻辑的实现工作了。gSOAP编译器可以集成C/C++和Fortran代码(通过一个Fortran到C的接口),嵌入式系统,其他SOAP程序提供的实时软件的资源和信息;可以跨越多个操作系统,语言环境以及在防火墙后的不同组织。
gSOAP使编写web服务的工作最小化了。gSOAP编译器生成SOAP的代码来序列化或反序列化C/C++的数据结构。gSOAP包含一个WSDL生成器,用它
来为你的web服务生成web服务的解释。gSOAP的解释器及导入器可以使用户不需要分析web服务的细节就可以实现一个客户端或服务端程序。
下面是gSOAP的一些特点:
gSOAP编译器可以根据用户定义的C和C++数据结构自动生成符合SOAP的实例化代码。
如果用生成纯C的代码,需要加编译选项-c
wsdl2h -c -o outfile.h(为自己任意起的头文件) infile.wsdl(提供的wsdl文件)
如果用生成纯C的代码,需要加编译选项-c
soapcpp2 -c outfile.h生成构架代码
soapC.cpp soapC.h soapServer.cpp soapStub.h stdsoap2.cpp stdsoap2.h stlvector.h WcmpServiceSOAP11Binding.nsmap(这个文件名根据outfile文件是不同的)
作为客户端,需要的代码为:
soapC.cpp soapC.h soapClient.cpp soapStub.h stdsoap2.cpp stdsoap2.h stlvector.h WcmpServiceSOAP11Binding.nsmap(这个文件名根据outfile文件是不同的)
#include "stdafx.h"
#include "soapH.h"
#include <stdio.h>
#include "calc.nsmap"
using
namespace
std;
int
main(
int
argc,
char
**argv)
{ SOAP_SOCKET m, s;
/* master and slave sockets */
struct
soap soap;
soap_init(&soap);
if
(argc < 2)
soap_serve(&soap);
/* serve as CGI application */
else
{ m = soap_bind(&soap, NULL,
atoi
(argv[1]), 100);
if
(!soap_valid_socket(m))
{ soap_print_fault(&soap, stderr);
exit
(-1);
}
fprintf
(stderr,
"Socket connection successful: master socket = %d\n"
, m);
for
( ; ; )
{ s = soap_accept(&soap);
fprintf
(stderr,
"Socket connection successful: slave socket = %d\n"
, s);
if
(!soap_valid_socket(s))
{ soap_print_fault(&soap, stderr);
exit
(-1);
}
soap_serve(&soap);
soap_end(&soap);
}
}
return
0;
}
int
__cdecl ns2__add(
struct
soap *soap,
double
a,
double
b,
double
&result){
result = a + b;
cout<<
"the result is ---"
<<result<<endl;
return
SOAP_OK;
}
int
__cdecl ns2__sub(
struct
soap *soap,
double
a,
double
b,
double
&result){
result = a - b;
return
SOAP_OK;
}
int
__cdecl ns2__mul(
struct
soap *soap,
double
a,
double
b,
double
&result){
result = a * b;
return
SOAP_OK;
}
int
__cdecl ns2__div(
struct
soap *soap,
double
a,
double
b,
double
&result){
if
(b)
result = a / b;
else
{
char
*s = (
char
*)soap_malloc(soap, 1024);
return
soap_sender_fault(soap,
"Division by zero"
, s);
}
return
SOAP_OK;
}
int
__cdecl ns2__pow(
struct
soap *soap,
double
a,
double
b,
double
&result){
result =
pow
(a, b);
if
(soap_errno == EDOM)
/* soap_errno is like errno, but compatible with Win32 */
{
char
*s = (
char
*)soap_malloc(soap, 1024);
sprintf
(s,
"Can't take the power of %f to %f"
, a, b);
return
soap_sender_fault(soap,
"Power function domain error"
, s);
}
return
SOAP_OK;
}
|
#include "stdafx.h"
#include "soapH.h"
#include "calc.nsmap"
//const char server[] = "http://websrv.cs.fsu.edu/~engelen/calcserver.cgi";
int
main(
int
argc,
char
* argv[])
{
struct
soap soap;
double
a, b, result;
if
(argc < 4)
{
fprintf
(stderr,
"Usage: [add|sub|mul|div|pow] num num\n"
);
exit
(0);
}
soap_init1(&soap, SOAP_XML_INDENT);
a =
strtod
(argv[2], NULL);
b =
strtod
(argv[3], NULL);
switch
(*argv[1])
{
case
'a'
:
soap_call_ns2__add(&soap, server,
""
, a, b, result);
break
;
case
's'
:
soap_call_ns2__sub(&soap, server,
""
, a, b, result);
break
;
case
'm'
:
soap_call_ns2__mul(&soap, server,
""
, a, b, result);
break
;
case
'd'
:
soap_call_ns2__div(&soap, server,
""
, a, b, result);
break
;
case
'p'
:
soap_call_ns2__pow(&soap, server,
""
, a, b, result);
break
;
default
:
fprintf
(stderr,
"Unknown command\n"
);
exit
(0);
}
if
(soap.error)
{ soap_print_fault(&soap, stderr);
exit
(1);
}
else
printf
(
"result = %g\n"
, result);
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return
0;
}
|