OSS C++ SDK V2

更新时间:
复制为 MD 格式

使用 OSS C++ SDK V2 在 C++ 应用中接入阿里云对象存储 OSS,实现文件的上传、下载和管理功能,适合高性能场景、嵌入式系统和桌面应用进行云端文件存储操作。

说明

OSS C++ SDK V2 当前为预览版(Preview),接口可能会调整,请关注 Github 仓库的版本说明获取最新变更。

Github | 示例代码 | 迁移指南 | deepwiki

快速接入

接入 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 传输层(curlwinhttp),不会默认启用。两者可以同时启用。

当同时启用 opensslmbedtls 时,openssl 优先生效。

vcpkg 提供以下可选 features,按需启用:

Feature

说明

curl

基于 libcurl 的 HTTP 传输层(需在安装命令中显式指定 [curl],不会默认启用)。

winhttp

基于 WinHTTP 的 HTTP 传输层(仅 Windows)。

openssl

使用 OpenSSL 进行哈希计算。

mbedtls

使用 mbedTLS 进行哈希计算。

encryption

启用客户端加密功能(非 Windows 平台需同时启用 opensslmbedtls)。

rtti

编译时启用 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 选项:

选项

说明

BUILD_SHARED_LIBS

构建动态库(默认 OFF,构建静态库)。

USE_CURL_TRANSPORT

使用 libcurl 作为 HTTP 传输层。

USE_WINHTTP_TRANSPORT

使用 WinHTTP 作为 HTTP 传输层(仅 Windows)。

USE_SYSTEM_CURL

使用系统已安装的 libcurl,而不是 SDK 自带版本。

USE_SYSTEM_OPENSSL

使用系统已安装的 OpenSSL。

USE_SYSTEM_MBEDTLS

使用系统已安装的 mbedTLS。

USE_STD_EXPECTED

使用 C++23 标准的 std::expected(默认使用 SDK 自带的兼容实现)。

ENABLE_ENCRYPTION

启用客户端加密功能。

ENABLE_RTTI

启用 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

  1. 在命令行界面执行以下命令来将环境变量设置追加到~/.bashrc 文件中。

    echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc
    echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
    1. 执行以下命令使变更生效。

      source ~/.bashrc
    2. 执行以下命令检查环境变量是否生效。

      echo $OSS_ACCESS_KEY_ID
      echo $OSS_ACCESS_KEY_SECRET

macOS

  1. 在终端中执行以下命令,查看默认 Shell 类型。

    echo $SHELL
    1. 根据默认 Shell 类型进行操作。

      Zsh

      1. 执行以下命令来将环境变量设置追加到~/.zshrc文件中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
      2. 执行以下命令使变更生效。

        source ~/.zshrc
      3. 执行以下命令检查环境变量是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

      Bash

      1. 执行以下命令来将环境变量设置追加到~/.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
      2. 执行以下命令使变更生效。

        source ~/.bash_profile
      3. 执行以下命令检查环境变量是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

Windows

CMD

  1. 在 CMD 中执行以下命令。

    setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID"
    setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
  2. 重新打开 CMD,执行以下命令检查环境变量是否生效。

    echo %OSS_ACCESS_KEY_ID%
    echo %OSS_ACCESS_KEY_SECRET%

PowerShell

  1. 在 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)
  2. 重新打开 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,如 cn-hangzhou
#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.cppAsyncCallbackOnSyncClient.cpp

OSSAsyncClient(异步)

原生异步模式:使用 OSSAsyncClient,每个操作有对应的 operationNameAsync() 方法,通过回调接收结果,不需要额外配置线程池。适用于需要大量并发操作的场景。

运行示例代码前,请将代码中的 <region-id> 替换为实际的地域和Endpoint,如 cn-hangzhou
#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。

客户端配置

客户端支持哪些配置?

参数名

说明

region

(必选)请求发送的区域

credentialsProvider

(必选)设置访问凭证

endpoint

访问域名

httpTransport

HTTP客户端,默认使用 Curl

retryMaxAttempts

HTTP请求时的最大尝试次数,默认值为 3

retryer

HTTP请求时的重试实现,默认使用 StandardRetryer(FullJitterBackoff)

connectTimeout

建立连接的超时时间(毫秒),默认值为 5000

readWriteTimeout

应用读写数据的超时时间(毫秒),默认值为 20000

insecureSkipVerify

是否跳过SSL证书校验,默认检查SSL证书

enabledRedirect

是否开启HTTP重定向,默认不开启

proxyHost

设置代理服务器

signatureVersion

签名版本,默认值为 v4,需要设置 region

signer

自定义签名器实现,设置后会覆盖 signatureVersion

disableSsl

不使用 HTTPS 请求,默认使用 HTTPS

usePathStyle

使用路径请求风格,即二级域名请求风格,默认为 Bucket 托管域名

useCName

是否使用自定义域名访问,默认不使用

useDualStackEndpoint

是否使用双栈域名访问,默认不使用

useAccelerateEndpoint

是否使用传输加速域名访问,默认不使用

useInternalEndpoint

是否使用内网域名访问,默认不使用

additionalHeaders

指定额外的签名请求头,V4签名下有效

userAgent

指定额外的 User-Agent 信息

disableClockSkewCorrection

关闭客户端与服务端的时钟漂移自动校正,默认开启校正

disableAutoDetectMimeType

关闭基于对象名的 Content-Type 自动检测,默认开启

disableUploadCRC64Check

关闭上传请求(PutObject、AppendObject、UploadPart、Uploader)的 CRC64 校验,默认开启

disableDownloadCRC64Check

关闭下载请求(GetObjectToFile、Downloader.DownloadFile)的 CRC64 校验,默认开启

executor

线程池实现,用于 OSSClient 的 asyncCall / asyncCallback。未设置时调用 asyncCall 会返回 NoExecutor 错误

asyncHttpTransport

OSSAsyncClient 使用的异步 HTTP 传输层,默认使用 CurlMultiTransport

scheduledExecutor

仅 OSSAsyncClient 使用的内部任务调度器,默认使用 SDK 内置实现

使用自定义域名

使用 OSS 默认域名访问时,可能会出现文件禁止访问、文件无法预览等问题;通过通过自定义域名访问OSS,不仅支持浏览器直接预览文件,还可结合 CDN 加速分发。

运行示例代码前,请将代码中的 <region-id> 替换为实际的地域和Endpoint,如 cn-hangzhou
#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;
}

超时控制

通过 connectTimeoutreadWriteTimeout 配置连接超时和读写超时时间(单位:毫秒)。

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 协议,设置 disableSsltrue

auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 使用 HTTP 协议
conf.disableSsl = true;

oss::OSSClient client(conf);

代理服务器

通过 proxyHost 配置代理服务器地址。

auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "<region-id>";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
// 设置代理服务器
conf.proxyHost = "http://your-proxy:8080";

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);

使用金融云域名

金融云地域的 OSS 使用特殊的 Endpoint。请在初始化时指定对应的 Endpoint。

auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "cn-hangzhou";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
conf.endpoint = "https://oss-cn-hzjbp-a-internal.aliyuncs.com";

oss::OSSClient client(conf);

使用政务云域名

政务云地域的 OSS 使用特殊的 Endpoint。请在初始化时指定对应的 Endpoint。

auto conf = oss::ClientConfiguration::loadDefault();
conf.region = "cn-north-2-gov-1";
conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();
conf.endpoint = "https://oss-cn-north-2-gov-1.aliyuncs.com";

oss::OSSClient client(conf);

自定义 HTTP 传输

C++ SDK V2 默认使用 Curl 作为 HTTP 传输层。你可以通过 httpTransport 替换为其他实现。Windows 平台还支持 WinHTTP。

自定义传输层示例,请参见 CurlCustomConfig.cppWinHttpCustomConfig.cpp

访问凭证配置

在使用 OSS C++ SDK V2 前,您需要配置访问凭证。C++ SDK V2 支持以下方式配置访问凭证:

如何选择凭证方式?

凭证方式

适用场景

是否需要前置 AK 或 STS Token

底层实现的凭证

凭证有效期

凭证轮转或刷新方式

使用 RAM 用户的 AK

部署运行在安全、稳定且不易受外部攻击的环境的应用程序,无需频繁轮转凭证就可以长期访问云服务

AK

长期

手动轮转

使用 STS 临时凭证

部署运行在不可信的环境的应用程序,希望能控制访问的有效期、权限

STS Token

临时

手动刷新

使用 RAMRoleARN

需要授权访问云服务,例如跨阿里云账号访问云服务的应用程序

STS Token

临时

自动刷新

使用 ECSRAMRole

部署运行在阿里云 ECS 实例、ECI 实例、容器服务 Kubernetes 版的 Worker 节点中的应用程序

STS Token

临时

自动刷新

使用 OIDCRoleARN

部署运行在阿里云的容器服务 Kubernetes 版的 Worker 节点中的不可信应用程序

STS Token

临时

自动刷新

使用匿名访问

访问公共读取权限的 OSS 资源

-

-

使用自定义凭证

如果以上凭证配置方式都不满足要求时,您可以自定义获取凭证的方式

自定义

自定义

自定义

自定义

使用 RAM 用户的 AK

如果您的应用程序部署在安全、稳定且不易被外部访问的环境中,可以使用 RAM 用户的 AccessKey。

环境变量(推荐)

通过环境变量 OSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRET 获取凭证。

  1. 使用 RAM 用户 AccessKey 配置环境变量。

    Linux

    1. 在命令行界面执行以下命令来将环境变量设置追加到 ~/.bashrc 文件中。

      echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc
      echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
    2. 执行以下命令使变更生效。

      source ~/.bashrc
    3. 执行以下命令检查环境变量是否生效。

      echo $OSS_ACCESS_KEY_ID
      echo $OSS_ACCESS_KEY_SECRET

    macOS

    1. 在终端中执行以下命令,查看默认 Shell 类型。

      echo $SHELL
    2. 根据默认 Shell 类型进行操作。

      Zsh

      1. 执行以下命令将环境变量设置追加到 ~/.zshrc 文件中。

        echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc
        echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
      2. 执行以下命令使变更生效。

        source ~/.zshrc
      3. 执行以下命令检查环境变量是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

      Bash

      1. 执行以下命令将环境变量设置追加到 ~/.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
      2. 执行以下命令使变更生效。

        source ~/.bash_profile
      3. 执行以下命令检查环境变量是否生效。

        echo $OSS_ACCESS_KEY_ID
        echo $OSS_ACCESS_KEY_SECRET

    Windows

    CMD

    1. 在 CMD 中执行以下命令。

      setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID"
      setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
    2. 重新打开 CMD,执行以下命令检查环境变量是否生效。

      echo %OSS_ACCESS_KEY_ID%
      echo %OSS_ACCESS_KEY_SECRET%

    PowerShell

    1. 在 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)
    2. 重新打开 PowerShell,执行以下命令检查环境变量是否生效。

      [System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_ID', [System.EnvironmentVariableTarget]::User)
      [System.Environment]::GetEnvironmentVariable('OSS_ACCESS_KEY_SECRET', [System.EnvironmentVariableTarget]::User)
  2. 修改系统环境变量后,请重启或刷新您的编译运行环境,包括 IDE、命令行界面、其他桌面应用程序及后台服务,以确保最新的系统环境变量成功加载。

  3. 使用环境变量来传递凭证信息。

    运行示例代码前,请将代码中的 <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_IDOSS_ACCESS_KEY_SECRETOSS_SESSION_TOKEN 获取临时凭证。

  1. 使用临时身份凭证设置环境变量。

    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>
  2. 使用环境变量来传递凭证信息。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 使用。

  1. 安装依赖。

    vcpkg install alibabacloud-credentials-cpp
  2. 在 CMakeLists.txt 中添加依赖。

    find_package(alibabacloud_credentials REQUIRED)
  3. 通过 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)
    //   - 密钥管理服务(如 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

同步

operationName(request)

-

基于 future 异步

asyncCall(request)(需配置 conf.executor

asyncCall(request)

基于 callback 异步

asyncCallback(request, cb)(需配置 conf.executor

operationNameAsync(request, cb)

取消请求

长时间运行的操作可以通过 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 提供了丰富的示例代码,帮助您快速上手。

功能分类

示例说明

同步版本

异步版本

存储空间

创建存储空间

PutBucket.cpp

PutBucket.cpp

列举存储空间

ListBuckets.cpp

ListBuckets.cpp

删除存储空间

DeleteBucket.cpp

DeleteBucket.cpp

获取存储空间信息

GetBucketInfo.cpp

GetBucketInfo.cpp

获取存储空间地域

GetBucketLocation.cpp

GetBucketLocation.cpp

文件上传

简单上传

PutObject.cpp

PutObject.cpp

追加上传

AppendObject.cpp

AppendObject.cpp

分片上传

UploadPart.cpp

UploadPart.cpp

分片拷贝

UploadPartCopy.cpp

UploadPartCopy.cpp

文件下载

简单下载

GetObject.cpp

GetObject.cpp

拷贝文件

CopyObject.cpp

CopyObject.cpp

文件管理

列举文件

ListObjects.cpp

ListObjects.cpp

列举文件 V2

ListObjectsV2.cpp

ListObjectsV2.cpp

删除文件

DeleteObject.cpp

DeleteObject.cpp

批量删除文件

DeleteMultipleObjects.cpp

DeleteMultipleObjects.cpp

获取文件元数据

HeadObject.cpp

HeadObject.cpp

获取文件简化元数据

GetObjectMeta.cpp

GetObjectMeta.cpp

归档文件

解冻归档文件

RestoreObject.cpp

RestoreObject.cpp

清理已解冻文件

CleanRestoredObject.cpp

CleanRestoredObject.cpp

软链接

创建软链接

PutSymlink.cpp

PutSymlink.cpp

获取软链接

GetSymlink.cpp

GetSymlink.cpp

对象标签

设置对象标签

PutObjectTagging.cpp

PutObjectTagging.cpp

获取对象标签

GetObjectTagging.cpp

GetObjectTagging.cpp

删除对象标签

DeleteObjectTagging.cpp

DeleteObjectTagging.cpp

访问控制

设置存储空间 ACL

PutBucketAcl.cpp

PutBucketAcl.cpp

获取存储空间 ACL

GetBucketAcl.cpp

GetBucketAcl.cpp

设置文件 ACL

PutObjectAcl.cpp

PutObjectAcl.cpp

版本控制

设置版本控制

PutBucketVersioning.cpp

PutBucketVersioning.cpp

获取版本控制状态

GetBucketVersioning.cpp

GetBucketVersioning.cpp

列举文件版本

ListObjectVersions.cpp

ListObjectVersions.cpp

防盗链

设置防盗链

PutBucketReferer.cpp

PutBucketReferer.cpp

获取防盗链配置

GetBucketReferer.cpp

GetBucketReferer.cpp

系统功能

查询 Endpoint 信息

DescribeRegions.cpp

DescribeRegions.cpp

预签名 URL

预签名下载 URL

PresignGetObject.cpp

-

预签名上传 URL

PresignPutObject.cpp

-

预签名 Head URL

PresignHeadObject.cpp

-

预签名分片上传 URL

PresignUploadPart.cpp

-

泛型 API

通过 invokeOperation 调用

InvokeOperation.cpp

-

分页器(Paginator)

列举所有存储空间

ListBucketsPaginator.cpp

-

列举所有文件(推荐)

ListObjectsV2Paginator.cpp

-

列举所有文件版本

ListObjectVersionsPaginator.cpp

-

列举所有已上传分片

ListPartsPaginator.cpp

-

列举所有分片上传任务

ListMultipartUploadsPaginator.cpp

-

列举所有文件(旧接口,不推荐)

ListObjectsPaginator.cpp

-

场景示例

SinkFactory 系列(无额外拷贝下载、断点续传、CRC 校验等)

samples/scenario/sink-factory

-

在 OSSClient 上使用 future / callback 异步

samples/scenario/sync-client-async

-

更多场景示例

samples/scenario

-