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 选项

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

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

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

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


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

文件名 用途
soapService.cpp C 风格的服务端框架 (等效于 soapcalcService.cpp 的 C 版本)
soapService.h 服务端头文件
soapC.cpp 公共序列化代码
ns.wsdl WSDL 服务描述文件
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

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

相关推荐
七七&5563 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
java坤坤3 小时前
GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
开发语言·后端·golang
元清加油3 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
健康平安的活着4 小时前
java之 junit4单元测试Mockito的使用
java·开发语言·单元测试
No0d1es4 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
DjangoJason5 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq
m0_480502646 小时前
Rust 入门 KV存储HashMap (十七)
java·开发语言·rust
大阳1236 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
YA3336 小时前
java基础(九)sql基础及索引
java·开发语言·sql
奇树谦7 小时前
QT|windwos桌面端应用程序开发,当连接多个显示器的时候,如何获取屏幕编号?
开发语言·qt