使用 OSS C++ SDK V2 在 C++ 應用中接入阿里雲Object Storage Service,實現檔案的上傳、下載和管理功能,適合高效能情境、嵌入式系統和案頭應用進行雲端檔案儲存體操作。
OSS C++ SDK V2 當前為預覽版(Preview),介面可能會調整,請關注 Github 倉庫的版本說明擷取最新變更。
快速接入
接入 OSS C++ SDK V2 的流程如下:
環境準備
C++17 及以上版本的編譯器(GCC 7+、Clang 5+、MSVC 2017+)。
CMake 3.15 及以上版本。
通過 cmake --version 命令查看 CMake 版本。如果當前環境沒有 CMake 或版本低於 3.15,請下載並安裝 CMake。安裝 SDK
建議使用 vcpkg 方式安裝 OSS C++ SDK V2。
vcpkg
使用 vcpkg 包管理器安裝:
vcpkg install alibabacloud-oss-cpp-sdk-v2[curl]
# Windows 環境可改用 WinHTTP 作為 HTTP 傳輸層
vcpkg install alibabacloud-oss-cpp-sdk-v2[winhttp]也可以通過 overlay port 從源碼安裝:
git clone https://github.com/aliyun/alibabacloud-oss-cpp-sdk-v2.git
vcpkg install alibabacloud-oss-cpp-sdk-v2[curl] --overlay-ports=alibabacloud-oss-cpp-sdk-v2/vcpkg --head必須顯式指定一種 HTTP 傳輸層(curl 或 winhttp),不會預設啟用。兩者可以同時啟用。
當同時啟用 openssl 和 mbedtls 時,openssl 優先生效。
vcpkg 提供以下可選 features,按需啟用:
Feature | 說明 |
| 基於 libcurl 的 HTTP 傳輸層(需在安裝命令中顯式指定 |
| 基於 WinHTTP 的 HTTP 傳輸層(僅 Windows)。 |
| 使用 OpenSSL 進行雜湊計算。 |
| 使用 mbedTLS 進行雜湊計算。 |
| 啟用用戶端加密功能(非 Windows 平台需同時啟用 |
| 編譯時間啟用 RTTI(運行時類型資訊)。 |
完整定義請參見 vcpkg/vcpkg.json。
源碼
從 Github 擷取最新版本的 OSS C++ SDK V2,並通過 CMake 構建和安裝:
git clone https://github.com/aliyun/alibabacloud-oss-cpp-sdk-v2.git
cd alibabacloud-oss-cpp-sdk-v2
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build . --target install源碼編譯時間支援以下 CMake 選項:
選項 | 說明 |
| 構建動態庫(預設 OFF,構建靜態庫)。 |
| 使用 libcurl 作為 HTTP 傳輸層。 |
| 使用 WinHTTP 作為 HTTP 傳輸層(僅 Windows)。 |
| 使用系統已安裝的 libcurl,而不是 SDK 內建版本。 |
| 使用系統已安裝的 OpenSSL。 |
| 使用系統已安裝的 mbedTLS。 |
| 使用 C++23 標準的 |
| 啟用用戶端加密功能。 |
| 啟用 RTTI(運行時類型資訊)。 |
在專案的 CMakeLists.txt 中添加依賴:
cmake_minimum_required(VERSION 3.15)
project(my-app)
find_package(alibabacloud_oss_v2 REQUIRED)
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE alibabacloud_oss_v2::oss)配置訪問憑證
將 RAM 使用者的 AccessKey 寫入環境變數作為憑證。
在RAM 控制台,建立使用永久 AccessKey 訪問的 RAM 使用者,儲存 AccessKey,然後為該使用者授予AliyunOSSFullAccess許可權。Linux
在命令列介面執行以下命令來將環境變數設定追加到
~/.bashrc檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc執行以下命令使變更生效。
source ~/.bashrc執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
在終端中執行以下命令,查看預設 Shell 類型。
echo $SHELL根據預設 Shell 類型進行操作。
Zsh
執行以下命令來將環境變數設定追加到
~/.zshrc檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc執行以下命令使變更生效。
source ~/.zshrc執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
執行以下命令來將環境變數設定追加到
~/.bash_profile檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile執行以下命令使變更生效。
source ~/.bash_profile執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Windows
CMD
在 CMD 中執行以下命令。
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"重新開啟 CMD,執行以下命令檢查環境變數是否生效。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
在 PowerShell 中執行以下命令。
[System.Environment]::SetEnvironmentVariable('OSS_ACCESS_KEY_ID', 'YOUR_ACCESS_KEY_ID', [System.EnvironmentVariableTarget]::User) [System.Environment]::SetEnvironmentVariable('OSS_ACCESS_KEY_SECRET', 'YOUR_ACCESS_KEY_SECRET', [System.EnvironmentVariableTarget]::User)重新開啟 PowerShell,執行以下命令檢查環境變數是否生效。
[System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_ID', [System.EnvironmentVariableTarget]::User) [System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_SECRET', [System.EnvironmentVariableTarget]::User)
初始化用戶端
SDK 提供三種請求模式:OSSClient(同步)、OSSClient(非同步)(基於線程池的非同步請求)和 OSSAsyncClient(非同步)(原生非同步請求),按業務情境選擇。以下樣本均使用 ListBuckets 介面列出當前帳號下的 Bucket。
OSSClient(同步)
如果需要等操作執行完成後再進行後續處理,選擇 OSSClient 同步模式。
運行範例程式碼前,請將代碼中的<region-id>替換為實際的地區和Endpoint,如ap-southeast-1。
#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
oss::OSSClient client(conf);
auto outcome = client.listBuckets(
oss::models::ListBucketsRequest());
if (!outcome.has_value()) {
auto& err = outcome.error();
std::cerr << "Error Code: " << err.getCode() << std::endl;
std::cerr << "Error Message: " << err.getMessage() << std::endl;
std::cerr << "Request ID: " << err.getRequestId() << std::endl;
return 1;
}
auto& result = outcome.value();
for (auto& bucket : result.getBuckets()) {
std::cout << "bucket: name:" << bucket.name
<< ", region:" << bucket.region
<< ", storageClass:" << bucket.storageClass
<< std::endl;
}
return 0;
}OSSClient(非同步)
基於線程池的非同步模式:仍然使用 OSSClient,但通過設定 conf.executor(線程池)後,調用 asyncCall() 把同步請求派發到線程池並發執行,返回 std::future 由調用方通過 get() 等待。
未設定conf.executor時,asyncCall()會返回NoExecutor錯誤。
#include <future>
#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
#include "alibabacloud/oss2/utils/DefaultExecutor.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 關鍵:配置線程池,開啟 OSSClient 的 asyncCall() 支援
conf.executor = std::make_shared<oss::DefaultExecutor>();
oss::OSSClient client(conf);
// 非同步呼叫,返回 std::future
auto future = client.asyncCall(oss::models::ListBucketsRequest());
// 通過 get() 等待結果(future 模式)
auto outcome = future.get();
if (!outcome.has_value()) {
auto& err = outcome.error();
std::cerr << "Error Code: " << err.getCode() << std::endl;
std::cerr << "Error Message: " << err.getMessage() << std::endl;
return 1;
}
auto& result = outcome.value();
for (auto& bucket : result.getBuckets()) {
std::cout << "bucket: name:" << bucket.name
<< ", region:" << bucket.region << std::endl;
}
return 0;
}完整樣本(含並發上傳/下載)請參見 AsyncCallOnSyncClient.cpp 與 AsyncCallbackOnSyncClient.cpp。
OSSAsyncClient(非同步)
原生非同步模式:使用 OSSAsyncClient,每個操作有對應的 operationNameAsync() 方法,通過回調接收結果,不需要額外配置線程池。適用於需要大量並行作業的情境。
運行範例程式碼前,請將代碼中的<region-id>替換為實際的地區和Endpoint,如ap-southeast-1。
#include <iostream>
#include <thread>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSAsyncClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
auto client = std::make_shared<oss::OSSAsyncClient>(conf);
client->listBucketsAsync(
oss::models::ListBucketsRequest(),
oss::ListBucketsAsyncCallback([](oss::ListBucketsOutcome outcome) {
if (!outcome.has_value()) {
auto& err = outcome.error();
std::cerr << "Error Code: " << err.getCode() << std::endl;
std::cerr << "Error Message: " << err.getMessage() << std::endl;
return;
}
auto& result = outcome.value();
for (auto& bucket : result.getBuckets()) {
std::cout << "bucket: name:" << bucket.name
<< ", region:" << bucket.region
<< ", storageClass:" << bucket.storageClass
<< std::endl;
}
}));
// 等待非同步作業完成
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}運行後將會看到當前帳號在所有地區下的 Bucket。
用戶端配置
使用自訂網域名
使用 OSS 預設網域名稱訪問時,可能會出現檔案禁止訪問、檔案無法預覽等問題;通過通過自訂網域名訪問OSS,不僅支援瀏覽器直接預覽檔案,還可結合 CDN 加速分發。
運行範例程式碼前,請將代碼中的<region-id>替換為實際的地區和Endpoint,如ap-southeast-1。
#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.endpoint = "https://your-custom-domain.com";
conf.useCName = true;
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
oss::OSSClient client(conf);
// 使用自訂網域名進行操作
auto outcome = client.putObject(
oss::models::PutObjectRequest()
.setBucket("your-bucket")
.setKey("your-key")
.setBody(oss::RequestBody::fromString("Hello, OSS!")));
if (!outcome.has_value()) {
auto& err = outcome.error();
std::cerr << "Error: " << err.getMessage() << std::endl;
return 1;
}
std::cout << "Upload successful" << std::endl;
return 0;
}逾時控制
通過 connectTimeout 和 readWriteTimeout 配置連線逾時和讀寫逾時時間(單位:毫秒)。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 設定連線逾時時間為 10 秒
conf.connectTimeout = 10000;
// 設定讀寫逾時時間為 30 秒
conf.readWriteTimeout = 30000;
oss::OSSClient client(conf);重試策略
C++ SDK V2 內建 StandardRetryer,預設使用 FullJitterBackoff 退避策略,最大嘗試次數為 3。你可以通過 retryMaxAttempts 設定最大嘗試次數。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 設定最大重試次數為 5
conf.retryMaxAttempts = 5;
oss::OSSClient client(conf);更多自訂重試策略樣本,請參見 CustomRetryStrategy.cpp。
HTTP/HTTPS 協議
預設使用 HTTPS 協議。如需使用 HTTP 協議,設定 disableSsl 為 true。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 使用 HTTP 協議
conf.disableSsl = true;
oss::OSSClient client(conf);使用內網網域名稱
當應用部署在ECS 上時,可以使用內網網域名稱訪問 OSS,減少公網流量費用。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 使用內網網域名稱
conf.useInternalEndpoint = true;
oss::OSSClient client(conf);使用傳輸加速網域名稱
通過傳輸加速網域名稱訪問 OSS,提升遠距離傳輸速度。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 使用傳輸加速網域名稱
conf.useAccelerateEndpoint = true;
oss::OSSClient client(conf);使用專有網域名稱
使用自訂網域名(CNAME)訪問 OSS。
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
conf.endpoint = "https://your-custom-domain.com";
conf.useCName = true;
oss::OSSClient client(conf);自訂 HTTP 傳輸
C++ SDK V2 預設使用 Curl 作為 HTTP 傳輸層。你可以通過 httpTransport 替換為其他實現。Windows 平台還支援 WinHTTP。
自訂傳輸層樣本,請參見 CurlCustomConfig.cpp 和 WinHttpCustomConfig.cpp。
訪問憑證配置
在使用 OSS C++ SDK V2 前,您需要配置訪問憑證。C++ SDK V2 支援以下方式配置訪問憑證:
使用 RAM 使用者的 AK
如果您的應用程式部署在安全、穩定且不易被外部存取的環境中,可以使用 RAM 使用者的 AccessKey。
環境變數(推薦)
通過環境變數 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET 擷取憑證。
使用 RAM 使用者 AccessKey 配置環境變數。
Linux
在命令列介面執行以下命令來將環境變數設定追加到
~/.bashrc檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc執行以下命令使變更生效。
source ~/.bashrc執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
在終端中執行以下命令,查看預設 Shell 類型。
echo $SHELL根據預設 Shell 類型進行操作。
Zsh
執行以下命令將環境變數設定追加到
~/.zshrc檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc執行以下命令使變更生效。
source ~/.zshrc執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
執行以下命令將環境變數設定追加到
~/.bash_profile檔案中。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile執行以下命令使變更生效。
source ~/.bash_profile執行以下命令檢查環境變數是否生效。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Windows
CMD
在 CMD 中執行以下命令。
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"重新開啟 CMD,執行以下命令檢查環境變數是否生效。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
在 PowerShell 中執行以下命令。
[System.Environment]::SetEnvironmentVariable('OSS_ACCESS_KEY_ID', 'YOUR_ACCESS_KEY_ID', [System.EnvironmentVariableTarget]::User) [System.Environment]::SetEnvironmentVariable('OSS_ACCESS_KEY_SECRET', 'YOUR_ACCESS_KEY_SECRET', [System.EnvironmentVariableTarget]::User)重新開啟 PowerShell,執行以下命令檢查環境變數是否生效。
[System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_ID', [System.EnvironmentVariableTarget]::User) [System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_SECRET', [System.EnvironmentVariableTarget]::User)
修改系統內容變數後,請重啟或重新整理您的編譯運行環境,包括 IDE、命令列介面、其他傳統型應用程式及後台服務,以確保最新的系統內容變數成功載入。
使用環境變數來傳遞憑證資訊。
運行範例程式碼前,請將代碼中的
<region-id>替換為實際的地區和 Endpoint,如cn-hangzhou。#include "alibabacloud/oss2/ClientConfiguration.h" #include "alibabacloud/oss2/OSSClient.h" #include "alibabacloud/oss2/credentials/CredentialsProvider.h" namespace oss = alibabacloud::oss2; int main() { auto conf = oss::ClientConfiguration::loadDefault(); conf.region = "<region-id>"; conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>(); oss::OSSClient client(conf); // 使用 client 進行操作 return 0; }
代碼中顯式設定
通過 StaticCredentialsProvider 顯式提供 AccessKey ID 和 AccessKey Secret。
此方式會在代碼中暴露 AccessKey,僅建議用於測試。生產環境建議使用環境變數或其他安全方式。
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::StaticCredentialsProvider>(
"YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET");
oss::OSSClient client(conf);
// 使用 client 進行操作
return 0;
}使用 STS 臨時憑證
如果您的應用程式需要臨時訪問 OSS,您可以通過 STS 服務擷取臨時身份憑證(AccessKey ID、AccessKey Secret 和 SecurityToken)初始化憑證提供者。需要注意的是,該方式需要您手動維護一個 STS Token,存在安全性風險和維護複雜度增加的風險。此外,如果您需要多次臨時訪問 OSS,您需要手動重新整理 STS Token。
如果您希望通過 SDK 的方式擷取 STS 臨時訪問憑證,請參見使用 STS 臨時訪問憑證訪問 OSS。
請注意,STS Token 產生時需指定到期時間,到期後自動失效不能再使用。
請注意區分通過 STS 服務擷取的 AccessKey ID 以
STS開頭,例如STS.L4aBSCSJVMuKg5U1****。
環境變數(推薦)
通過環境變數 OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET 和 OSS_SESSION_TOKEN 擷取臨時憑證。
使用臨時身份憑證設定環境變數。
Mac OS X / Linux / Unix
export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>Windows
set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>使用環境變數來傳遞憑證資訊。SDK 的
EnvironmentVariableCredentialsProvider會自動讀取上述三個環境變數。運行範例程式碼前,請將代碼中的
<region-id>替換為實際的地區和 Endpoint,如cn-hangzhou。#include "alibabacloud/oss2/ClientConfiguration.h" #include "alibabacloud/oss2/OSSClient.h" #include "alibabacloud/oss2/credentials/CredentialsProvider.h" namespace oss = alibabacloud::oss2; int main() { auto conf = oss::ClientConfiguration::loadDefault(); conf.region = "<region-id>"; // 自動讀取 OSS_ACCESS_KEY_ID / OSS_ACCESS_KEY_SECRET / OSS_SESSION_TOKEN conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>(); oss::OSSClient client(conf); // 使用 client 進行操作 return 0; }
代碼中顯式設定
通過 StaticCredentialsProvider 顯式提供臨時 AccessKey ID、AccessKey Secret 和 SecurityToken。
請勿將臨時憑據嵌入到生產環境的應用程式中,此方法僅用於測試目的。生產環境建議使用環境變數或通過 SDK 自動重新整理 STS Token 的方式。
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::StaticCredentialsProvider>(
"STS_ACCESS_KEY_ID", "STS_ACCESS_KEY_SECRET", "STS_SECURITY_TOKEN");
oss::OSSClient client(conf);
// 使用 client 進行操作
return 0;
}使用 RAMRoleARN / ECSRAMRole / OIDCRoleARN
對於 RAMRoleARN、ECSRAMRole、OIDCRoleARN 等憑證方式,建議通過 alibabacloud-credentials-cpp 庫配合 CredentialsProviderFunc 使用。
安裝依賴。
vcpkg install alibabacloud-credentials-cpp在 CMakeLists.txt 中添加依賴。
find_package(alibabacloud_credentials REQUIRED)通過
CredentialsProviderFunc整合。RAMRoleARN
#include "alibabacloud/oss2/ClientConfiguration.h" #include "alibabacloud/oss2/OSSClient.h" #include "alibabacloud/oss2/credentials/CredentialsProvider.h" #include <darabonba/core/Client.hpp> #include <alibabacloud/credential.hpp> namespace oss = alibabacloud::oss2; int main() { auto credConfig = std::make_shared<Alibabacloud_Credential::Config>(); // 憑證類型固定為 ram_role_arn credConfig->type = std::make_shared<std::string>("ram_role_arn"); // RAM 使用者的 AccessKey ID。建議通過環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID 注入,避免寫入程式碼 credConfig->accessKeyId = std::make_shared<std::string>("YOUR_ACCESS_KEY_ID"); // RAM 使用者的 AccessKey Secret。建議通過環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET 注入 credConfig->accessKeySecret = std::make_shared<std::string>("YOUR_ACCESS_KEY_SECRET"); // 要扮演的 RAM 角色 ARN,樣本:acs:ram::123456789012****:role/adminrole // 也可通過環境變數 ALIBABA_CLOUD_ROLE_ARN 設定 credConfig->roleArn = std::make_shared<std::string>("YOUR_ROLE_ARN"); // 角色會話名稱,用於審計區分。也可通過環境變數 ALIBABA_CLOUD_ROLE_SESSION_NAME 設定 credConfig->roleSessionName = std::make_shared<std::string>("your-session-name"); // (可選)通過 policy 進一步收窄許可權至最小集合,非必填 // 樣本:{"Statement":[{"Action":["oss:GetObject"],"Effect":"Allow","Resource":["*"]}],"Version":"1"} // credConfig->policy = std::make_shared<std::string>("<Policy>"); // (可選)角色會話有效期間,單位為秒,預設 3600 秒(1 小時),非必填 // credConfig->roleSessionExpiration = std::make_shared<long>(3600); auto credClient = std::make_shared<Alibabacloud_Credential::Client>(credConfig); auto conf = oss::ClientConfiguration::loadDefault(); conf.region = "<region-id>"; conf.credentialsProvider = std::make_shared<oss::CredentialsProviderFunc>( [credClient]() -> oss::Credentials { auto cred = credClient->getCredential(); auto ak = cred.getAccessKeyId(); auto sk = cred.getAccessKeySecret(); if (ak.empty() || sk.empty()) { return oss::Credentials::withRetryableError( "failed to get credentials from alibabacloud-credentials-cpp"); } auto token = cred.getSecurityToken(); return oss::Credentials(std::move(ak), std::move(sk), std::move(token)); }); oss::OSSClient client(conf); // 使用 client 進行操作 return 0; }ECSRAMRole
#include "alibabacloud/oss2/ClientConfiguration.h" #include "alibabacloud/oss2/OSSClient.h" #include "alibabacloud/oss2/credentials/CredentialsProvider.h" #include <darabonba/core/Client.hpp> #include <alibabacloud/credential.hpp> namespace oss = alibabacloud::oss2; int main() { auto credConfig = std::make_shared<Alibabacloud_Credential::Config>(); // 憑證類型固定為 ecs_ram_role credConfig->type = std::make_shared<std::string>("ecs_ram_role"); // 為 ECS 授予的 RAM 角色名稱。選擇性參數;不設定時 SDK 會自動從中繼資料服務檢索, // 強烈建議顯式設定以減少對中繼資料服務的請求 credConfig->roleName = std::make_shared<std::string>("YOUR_ECS_ROLE_NAME"); auto credClient = std::make_shared<Alibabacloud_Credential::Client>(credConfig); auto conf = oss::ClientConfiguration::loadDefault(); conf.region = "<region-id>"; conf.credentialsProvider = std::make_shared<oss::CredentialsProviderFunc>( [credClient]() -> oss::Credentials { auto cred = credClient->getCredential(); auto ak = cred.getAccessKeyId(); auto sk = cred.getAccessKeySecret(); if (ak.empty() || sk.empty()) { return oss::Credentials::withRetryableError( "failed to get credentials from alibabacloud-credentials-cpp"); } auto token = cred.getSecurityToken(); return oss::Credentials(std::move(ak), std::move(sk), std::move(token)); }); oss::OSSClient client(conf); // 使用 client 進行操作 return 0; }OIDCRoleARN
#include "alibabacloud/oss2/ClientConfiguration.h" #include "alibabacloud/oss2/OSSClient.h" #include "alibabacloud/oss2/credentials/CredentialsProvider.h" #include <darabonba/core/Client.hpp> #include <alibabacloud/credential.hpp> namespace oss = alibabacloud::oss2; int main() { auto credConfig = std::make_shared<Alibabacloud_Credential::Config>(); // 憑證類型固定為 oidc_role_arn credConfig->type = std::make_shared<std::string>("oidc_role_arn"); // 要扮演的 RAM 角色 ARN。也可通過環境變數 ALIBABA_CLOUD_ROLE_ARN 設定 credConfig->roleArn = std::make_shared<std::string>("YOUR_ROLE_ARN"); // OIDC 身份供應商 ARN。也可通過環境變數 ALIBABA_CLOUD_OIDC_PROVIDER_ARN 設定 credConfig->oidcProviderArn = std::make_shared<std::string>("YOUR_OIDC_PROVIDER_ARN"); // OIDC Token 檔案路徑,由 RRSA 自動掛載到 Pod 內。也可通過環境變數 ALIBABA_CLOUD_OIDC_TOKEN_FILE 設定 credConfig->oidcTokenFilePath = std::make_shared<std::string>("/var/run/secrets/tokens/oidc-token"); // 角色會話名稱,用於審計區分。也可通過環境變數 ALIBABA_CLOUD_ROLE_SESSION_NAME 設定 credConfig->roleSessionName = std::make_shared<std::string>("your-session-name"); // (可選)通過 policy 進一步收窄許可權,非必填 // credConfig->policy = std::make_shared<std::string>("<Policy>"); auto credClient = std::make_shared<Alibabacloud_Credential::Client>(credConfig); auto conf = oss::ClientConfiguration::loadDefault(); conf.region = "<region-id>"; conf.credentialsProvider = std::make_shared<oss::CredentialsProviderFunc>( [credClient]() -> oss::Credentials { auto cred = credClient->getCredential(); auto ak = cred.getAccessKeyId(); auto sk = cred.getAccessKeySecret(); if (ak.empty() || sk.empty()) { return oss::Credentials::withRetryableError( "failed to get credentials from alibabacloud-credentials-cpp"); } auto token = cred.getSecurityToken(); return oss::Credentials(std::move(ak), std::move(sk), std::move(token)); }); oss::OSSClient client(conf); // 使用 client 進行操作 return 0; }更多憑證樣本,請參見 credentials 樣本。
使用匿名訪問
如果請求的 Bucket 和 Object 已設定公用讀取許可權,可以使用匿名訪問。
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
namespace oss = alibabacloud::oss2;
int main() {
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::AnonymousCredentialsProvider>();
oss::OSSClient client(conf);
// 使用 client 進行操作
return 0;
}自訂憑證提供者
如果以上憑證方式不能滿足需求,您可以通過 CredentialsProviderFunc 自訂憑證擷取邏輯。
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"
#include <cstdlib>
namespace oss = alibabacloud::oss2;
// 樣本:從自訂環境變數或設定檔載入憑證
static oss::Credentials loadCredentialsFromCustomSource() {
// 在實際應用中,您可以從以下來源讀取憑證:
// - 設定檔(如 ~/.ossrc)
// - Key Management Service(如 HashiCorp Vault、KMS)
// - 中繼資料服務
// - 資料庫
const char* ak = std::getenv("MY_APP_ACCESS_KEY_ID");
const char* sk = std::getenv("MY_APP_ACCESS_KEY_SECRET");
const char* token = std::getenv("MY_APP_SESSION_TOKEN");
if (!ak || !sk) {
// 錯誤資訊會傳播到 OperationError::getMessage()
return oss::Credentials::withError(
"MY_APP_ACCESS_KEY_ID and MY_APP_ACCESS_KEY_SECRET must be set");
// 對於臨時性故障(如網路逾時),使用 withRetryableError,
// SDK 將自動重試擷取憑證。
// return oss::Credentials::withRetryableError("...");
}
return oss::Credentials(ak, sk, token ? token : "");
}
int main() {
// 自訂憑證提供函數在每次需要憑證時被調用,
// 因此可以實現輪換、重新整理或緩衝邏輯。
auto provider = std::make_shared<oss::CredentialsProviderFunc>(
loadCredentialsFromCustomSource);
auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = provider;
oss::OSSClient client(conf);
// 使用 client 進行操作
return 0;
}調用 API 操作
OSS C++ SDK V2 中所有 API 操作都遵循統一的命名規則與調用方式。本節介紹介面命名、調用模式、請求取消和錯誤處理。
介面命名規則
所有方法名採用 camelCase 風格,每個操作接受一個 <OperationName>Request 參數並返回 <OperationName>Outcome(即 Outcome<Result, Error>)。
OSSClient(同步):
OutcomeType operationName(const models::OperationNameRequest& request, const OperationOptions* options = nullptr)OSSAsyncClient(原生非同步):
void operationNameAsync(const models::OperationNameRequest& request, const OperationNameAsyncCallback& callback, const OperationOptions* options = nullptr)調用方式
調用模式 | OSSClient | OSSAsyncClient |
同步 |
| - |
基於 future 非同步 |
|
|
基於 callback 非同步 |
|
|
取消請求
長時間啟動並執行操作可以通過 CancellationToken 取消。在 OperationOptions 中傳入 cancellationToken,OSS C++ SDK V2 提供以下兩種取消模式:
立即取消
通過 CancellationTokenSource::cancel(),從其他線程主動中斷進行中的請求。
// 從其他線程主動取消請求
auto cts = oss::CancellationTokenSource::create();
oss::OperationOptions opts;
opts.cancellationToken = cts->getToken();
// 在另一線程發起請求
auto future = std::async([&]() {
return client.getObject(request, &opts);
});
// 從當前線程取消
cts->cancel();基於 deadline 的逾時取消
通過 cancelAfter() 設定逾時時間長度,到點自動觸發取消,適用於"逾時後放棄"的情境。
// 設定 30 秒逾時自動取消
auto cts = oss::CancellationTokenSource::create();
cts->cancelAfter(std::chrono::seconds(30));
oss::OperationOptions opts;
opts.cancellationToken = cts->getToken();
auto outcome = client.getObject(request, &opts);錯誤處理
OSS C++ SDK V2 使用 Outcome<Result, Error>,介面相容 std::expected。判斷成功使用 has_value(),成功通過 value()(或 *outcome)取結果,失敗通過 error() 取錯誤對象。
auto outcome = client.putObject(request);
if (!outcome.has_value()) {
auto& err = outcome.error();
std::cerr << "錯誤碼: " << err.getCode() << std::endl;
std::cerr << "錯誤資訊: " << err.getMessage() << std::endl;
std::cerr << "EC: " << err.getEC() << std::endl;
std::cerr << "請求 ID: " << err.getRequestId() << std::endl;
std::cerr << "請求地址: " << err.getRequestTarget() << std::endl;
}使用 -DUSE_STD_EXPECTED=ON(C++23)構建時,Outcome 將成為 std::expected 的類型別名,支援 .and_then()、.transform()、.or_else() 等一元操作。
範例程式碼
OSS C++ SDK V2 提供了豐富的範例程式碼,協助您快速上手。
功能分類 | 樣本說明 | 同步版本 | 非同步版本 |
儲存空間 | 建立儲存空間 | ||
列舉儲存空間 | |||
刪除儲存空間 | |||
擷取儲存空間資訊 | |||
擷取儲存空間地區 | |||
檔案上傳 | 簡單上傳 | ||
追加上傳 | |||
分區上傳 | |||
分區拷貝 | |||
檔案下載 | 簡單下載 | ||
拷貝檔案 | |||
檔案管理 | 列舉檔案 | ||
列舉檔案 V2 | |||
刪除檔案 | |||
大量刪除檔案 | |||
擷取檔案中繼資料 | |||
擷取檔案簡化中繼資料 | |||
歸檔檔案 | 解凍歸檔檔案 | ||
清理已解凍檔案 | |||
軟連結 | 建立軟連結 | ||
擷取軟連結 | |||
對象標籤 | 設定對象標籤 | ||
擷取對象標籤 | |||
刪除對象標籤 | |||
存取控制 | 設定儲存空間 ACL | ||
擷取儲存空間 ACL | |||
設定檔案 ACL | |||
版本控制 | 設定版本控制 | ||
擷取版本控制狀態 | |||
列舉檔案版本 | |||
防盜鏈 | 設定防盜鏈 | ||
擷取防盜鏈配置 | |||
系統功能 | 查詢 Endpoint 資訊 | ||
預簽名 URL | 預簽名下載 URL | - | |
預簽名上傳 URL | - | ||
預簽名 Head URL | - | ||
預簽名分區上傳 URL | - | ||
泛型 API | 通過 invokeOperation 調用 | - | |
分頁器(Paginator) | 列舉所有儲存空間 | - | |
列舉所有檔案(推薦) | - | ||
列舉所有檔案版本 | - | ||
列舉所有已上傳分區 | - | ||
列舉所有分區上傳任務 | - | ||
列舉所有檔案(舊介面,不推薦) | - | ||
情境樣本 | SinkFactory 系列(無額外拷貝下載、斷點續傳、CRC 校正等) | - | |
在 OSSClient 上使用 future / callback 非同步 | - | ||
更多情境樣本 | - |