創建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
?前綴對應的URI:http://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
。兩種風格功能等效,選擇取決于項目需求。