当前位置: 首页 > java >正文

Ubuntu22 上,用C++ gSoap 创建一个简单的webservice

创建calc.h

// calc.h
// gSOAP 服务定义
int ns__add(double a, double b, double &result);
int ns__subtract(double a, double b, double &result);

==========================

创建my_server.cpp

#include "soapService.h"
#include "ns.nsmap" 

class MyService : public Service {
public:
int add(double a, double b, double &result) override {
result = a + b;
return SOAP_OK;
}
int subtract(double a, double b, double &result) override {
result = a + b;
return SOAP_OK;
}
};

int main() {
MyService service;
service.run(8080); // 启动服务
return 0;
}

========================

在soapService.cpp

增加两个函数

int Service::add(double a, double b, double &result) {
result = a + b;
return SOAP_OK;
}

int Service::subtract(double a, double b, double &result) {
result = a - b;
return SOAP_OK;
}

==============================

用C++风格,编译生成server

g++ -std=c++11 my_server.cpp soapC.cpp soapService.cpp -o server -lgsoap++

运行

./server

===============================

查看namespace

root@102:/usr/local/src/testCode# cat ns.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="Service" targetNamespace="http://tempuri.org/ns.xsd/Service.wsdl" xmlns:tns="http://tempuri.org/ns.xsd/Service.wsdl" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://tempuri.org/ns.xsd"

------------------

ns 前缀对应的URIhttp://tempuri.org/ns.xsd,后面的curl测试会用的namespace -----H 'SOAPAction: "http://tempuri.org/ns.xsd#add"' \

------------------------

用curl 测试

curl -X POST http://localhost:8080 \
-H "Content-Type: text/xml" \
-H 'SOAPAction: "http://tempuri.org/ns.xsd#add"' \
-d '<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://tempuri.org/ns.xsd">
<soapenv:Header/>
<soapenv:Body>
<ns:add>
<a>10.5</a>
<b>2.3</b>
</ns:add>
</soapenv:Body>
</soapenv:Envelope>'

===============================

您观察到的现象是正确的,这是因为您使用了 -S 选项(生成纯 C 代码风格的服务端),而之前的示例是基于 C++ 风格的代码生成(使用 -j 选项)。以下是详细解释和解决方案:


1. 关键区别:-S 和 -j 选项

选项生成文件命名代码风格适用场景
-SsoapService.cppC 风格(函数式)纯 C 项目
-jsoap**calc**Service.cppC++ 风格(面向对象)C++ 项目

您的命令 soapcpp2 -j -S -x calc.h 中:

  • -j 和 -S 同时存在时,-S 优先级更高,因此生成的是 C 风格文件 soapService.cpp

  • 如果去掉 -S,会生成 C++ 风格的 soapcalcService.cpp


2. 生成的文件说明(您的实际输出)

文件名用途
soapService.cppC 风格的服务端框架(等效于 soapcalcService.cpp 的 C 版本)
soapService.h服务端头文件
soapC.cpp公共序列化代码
ns.wsdlWSDL 服务描述文件
ns.nsmap命名空间映射表

3. 如何生成 C++ 风格代码?

移除 -S 选项,仅保留 -j

bash

soapcpp2 -j -x calc.h

此时会生成:

  • soapcalcService.cpp(C++ 服务端框架)

  • calcService.h(C++ 服务类头文件)


4. 您的下一步选择

选项 1:继续使用 C 风格(当前生成的文件)
  • 服务端实现示例(直接修改 soapService.cpp):

    c

    #include "soapH.h"int ns__add(struct soap *soap, double a, double b, double *result) {*result = a + b;return SOAP_OK;
    }int main() {struct soap soap;soap_init(&soap);soap_serve(&soap); // 启动服务(默认端口8080)return 0;
    }
  • 编译命令

    bash

    gcc soapService.cpp soapC.cpp -o server -lgsoap
选项 2:改用 C++ 风格(推荐)

重新生成代码:

bash

soapcpp2 -j -x calc.h
  • 服务端实现示例(继承 calcService 类):

    cpp

    #include "calcService.h"class MyService : public calcService {
    public:int add(double a, double b, double &result) override {result = a + b;return SOAP_OK;}
    };int main() {MyService service;service.run(8080); // 启动服务return 0;
    }
  • 编译命令

    bash

    g++ -std=c++11 my_server.cpp soapC.cpp soapcalcService.cpp -o server -lgsoap++

5. 为什么文件名不同?

  • C 风格:统一命名为 soapService.cpp

  • C++ 风格:文件名包含接口前缀(如 soap**calc**Service.cpp),便于多接口区分。


总结

  • 您当前生成的是 C 风格 代码(因 -S 选项)。

  • 如需 C++ 风格,移除 -S 并保留 -j

  • 两种风格功能等效,选择取决于项目需求。

http://www.xdnf.cn/news/16243.html

相关文章:

  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-24,(知识点:二极管基础知识,单向导电性)
  • 【09】C#入门到精通——C# 结构体对齐 与 常用数据 对应关系
  • CF每日5题(1500-1600)
  • node.js中的path模块
  • 技嘉z370主板开启vtx
  • windows11通过wsl安装Ubuntu到D盘,安装docker及宝塔面板
  • 【STM32】FreeRTOS 任务的删除(三)
  • 《 java 随想录》| 数组
  • Java学习日记_廖万忠
  • 支持OCR和AI解释的Web PDF阅读器:解决大文档阅读难题
  • uni-appDay02
  • #来昇腾学AI 【十天成长计划】大模型LLM Prompt初级班
  • Java学习----工厂方法模式
  • 深入理解 eMMC RPMB 与 OP-TEE 在 Linux 系统中的应用开发
  • day62-可观测性建设-全链路监控zabbix+grafana
  • 爬虫算法原理解析
  • Windows环境下 Go项目迁移至Ubuntu(WSL) 以部署filebeat为例
  • MinIO 版本管理实践指南(附完整 Go 示例)
  • MySQL深度理解-MySQL索引优化
  • 二分查找----5.寻找旋转排序数组中的最小值
  • Android Activity与Fragment生命周期变化
  • 谈谈ArrayList与Vector的理解?
  • NOTEPAD!NPCommand函数分析之comdlg32!GetSaveFileNameW--windows记事本源代码分析
  • TechGPT3部署
  • 【STM32】FreeRTOS 任务的创建(二)
  • 深入理解大语言模型生成参数:temperature、top\_k、top\_p 等全解析
  • EasyExcel 模板导出数据 + 自定义策略(合并单元格)
  • vue 项目中 components 和 views 包下的组件功能区别对比,示例演示
  • AudioLLM 开源项目了解学习
  • 网络编程——聊天程序实现