寺委书记

Good good study, day day up!

导航

gSOAP契约函数返回结构体(返回多个值)

Posted on 2011-12-15 10:10  MonkChen  阅读(1984)  评论(0)    收藏  举报

gSOAP服务端函数只能返回一个值,当然这个值可以是自定义类型(比如结构体,用来返回多个值),不过我在相关文档没有找到说明如何来做,查了一些论坛资料,终于解决,现总结如下:

1. 定义契约(服务)头文件,calc.h

// Contents of file "calc.h": 
typedef double xsd__double; 
typedef char *xsd__string;  

class ns_student  
{  
  public:  
  xsd__string name;  
};  
struct ns__getstudentResponse {ns_student return_;};  

int ns__getstudent(struct ns__getstudentResponse &ret);
int ns__add(xsd__double a, xsd__double b, xsd__double &result); 
int ns__sub(xsd__double a, xsd__double b, xsd__double &result); 
int ns__sqrt(xsd__double a, xsd__double &result); 

 

2. 用soapcpp2 生成相关文件:soapcpp2 calc.h

   我写了个批处理文件,每次calc.h有修改,我就双击批处理文件,省得每次都要敲命令

 

3. 编写契约实现代码:calc.cpp

   注意: 在calc.cpp里,引用的头文件是soapStub.h,而不再是calc.h,其中有一段是:

 

 1 /******************************************************************************\
 2  *                                                                            *
 3  * Server-Side Operations                                                     *
 4  *                                                                            *
 5 \******************************************************************************/
 6 
 7 
 8 SOAP_FMAC5 int SOAP_FMAC6 ns__getstudent(struct soap*, struct ns__getstudentResponse &ret);
 9 
10 SOAP_FMAC5 int SOAP_FMAC6 ns__add(struct soap*, double a, double b, double &result);
11 
12 SOAP_FMAC5 int SOAP_FMAC6 ns__sub(struct soap*, double a, double b, double &result);
13 
14 SOAP_FMAC5 int SOAP_FMAC6 ns__sqrt(struct soap*, double a, double &result);

这就是我们在calc.cpp要实现的函数,calc.cpp内容如下

 

#include "soapH.h" 
#include "soapStub.h"

// Implementation of the "add" service operation: 
int ns__add(struct soap *soap, double a, double b, double &result) 

   result = a + b; 
   return SOAP_OK; 

// Implementation of the "sub" service operation: 
int ns__sub(struct soap *soap, double a, double b, double &result) 

   result = a - b; 
   return SOAP_OK; 

// Implementation of the "sqrt" service operation: 
int ns__sqrt(struct soap *soap, double a, double &result) 

   if (a >= 0
   { 
      result = sqrt(a); 
      return SOAP_OK; 
   } 
   else
      return soap_receiver_fault(soap, "Square root of negative number""I can only take the square root of a non-negative number"); 


int ns__getstudent(struct soap*, struct ns__getstudentResponse &ret)
{
    ret.return_.name = "name";
    return SOAP_OK;
}

 

4.这里我用独立程序(控制台程序)来承载服务,当然也可以用cgi方式,不过不是本文讨论的范围。添加main.cpp,实现主函数,内容如下:

 

#include "ns.nsmap"


int  http_get(struct   soap   *soap) 

    FILE*fd = NULL;
    fd = fopen("ns.wsdl""rb"); //open WSDL file to copy
    if (!fd)
    {
        return 404//return HTTP not found error
    }
    soap->http_content = "text/xml";  //HTTP header with text /xml content
    soap_response(soap,SOAP_FILE);
    for(;;)
    {
        size_t r = fread(soap->tmpbuf,1sizeof(soap->tmpbuf), fd);
        if (!r)
        {
                break;
        }
        if (soap_send_raw(soap, soap->tmpbuf, r))
        {
                break//cannot send, but little we can do about that
        }
    }
    fclose(fd);
    soap_end_send(soap);
    return SOAP_OK; 
}

void main(int argc, char **argv) 

   struct soap soap; 
   int m, s; // master and slave sockets 
   soap_init(&soap); 
   soap.fget = http_get;
   m = soap_bind(&soap, "192.168.1.19"8008100); 
   if (m < 0
      soap_print_fault(&soap, stderr); 
   else
   { 
      fprintf(stderr, "Socket connection successful: master socket = %d\n", m); 
      for (int i = 1; ; i++) 
      {
         s = soap_accept(&soap); 
         if (s < 0
         { 
            soap_print_fault(&soap, stderr); 
            break
         } 
         fprintf(stderr, "%d: accepted connection from IP=%d.%d.%d.%d socket=%d", i, 
            (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s); 
         if (soap_serve(&soap) != SOAP_OK) // process RPC request 
            soap_print_fault(&soap, stderr); // print error 
         fprintf(stderr, "request served\n"); 
         soap_destroy(&soap); // clean up class instances 
         soap_end(&soap); // clean up everything and close socket 
      } 
   } 
   soap_done(&soap); // close master socket and detach context

 

5.修改ns.wsdl

将location属性修改和main函数里面的bind匹配,否则会出现连接错误

<service name="Service">
 <documentation>gSOAP 2.8.5 generated service definition</documentation>
 <port name="Service" binding="tns:Service">
  <SOAP:address location="http://192.168.1.19:8008"/>
 </port>
</service>

 

6.包含文件,整个工程的文件结构如图:

 

 

6.编译,ok