惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
B
Blog
WordPress大学
WordPress大学
Project Zero
Project Zero
P
Palo Alto Networks Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
T
Tailwind CSS Blog
Forbes - Security
Forbes - Security
F
Full Disclosure
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hacker News: Ask HN
Hacker News: Ask HN
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
G
Google Developers Blog
J
Java Code Geeks
Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
O
OpenAI News
Spread Privacy
Spread Privacy
MongoDB | Blog
MongoDB | Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Cybersecurity and Infrastructure Security Agency CISA
S
Securelist
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
IT之家
IT之家
U
Unit 42
腾讯CDC
S
Security Affairs
C
Cisco Blogs
Schneier on Security
Schneier on Security
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
宝玉的分享
宝玉的分享
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss

博客园 - MonkChen

使用阿里云Java SDK 实现 DDNS Ehcache3.4 XML配置硬盘存储 Tesseract训练 Postgresql Jsonb字段内含数组属性的删除元素操作 Activiti开启SQL Log Drools mvel方言drl断点调试方法 Openfire 编译插件 mysql数据备份 Silverlight 缓存控制策略 Silverlight ComboBox with TreeView silverlight5 net.tcpBinding 跨域策略的解决 WCF CustomBinding 身份验证 CMF Android !No Launcher activity found错误 Android SDK Manager 无法获取列表的解决 Silverlight跨域调用gSoap/Java web service 以及wsdl文件的修改 java jax-ws发布含有DateTime字段的实体的webservice gSoap中文乱码解决 RTMP协议
gSOAP契约函数返回结构体(返回多个值)
MonkChen · 2011-12-15 · via 博客园 - MonkChen

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