0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows の C++ で Google Cloud Storage を操作する

Last updated at Posted at 2025-10-27

はじめに

この記事は google-cloud-cpp を使って C++ で Google Cloud Storage を操作したものです。

基本的には 公式の資料 と サンプル (Bucket Object) などを参考に Visual Studio で実行しています。

作業には事前に Google Cloud コンソールでサービスアカウントを作成する必要があります。

サービスアカウントの作成

コンソールからサービスアカウントを作成し、C++ のコードで使う鍵ファイル(json) を取得する。

image.png

image.png

image.png

image.png

image.png

image.png

取得した json ファイルは C:\cxx\cxx-project_credentials.json として保存し、C++ のソースコードから参照する。

C++ プロジェクトの作成

コンソールアプリケーションとして、GCS を操作するためのプロジェクトを作成。

image.png

image.png

image.png

C++ 17 に変更。(任意)

google-cloud-cpp のビルド

Github から取得したソースをビルドする。
その際、C++17 としてコンパイルするために、triplet ファイルを配置して vcpkg の実行時に指定している。

git clone
C:\cxx\project\02-gcp-gs>git clone https://github.com/microsoft/vcpkg.git google-cloud-cpp\repo
triplet を配置
C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo\triplets\community\x64-windows-cxx17.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)

set(VCPKG_C_LANGUAGE_STANDARD 17)
set(VCPKG_CXX_LANGUAGE_STANDARD 17)
vcpkg の生成
C:\cxx\project\02-gcp-gs>cd google-cloud-cpp\repo

C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo>bootstrap-vcpkg.bat
Downloading https://github.com/microsoft/vcpkg-tool/releases/download/2025-10-16/vcpkg.exe -> C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo\vcpkg.exe... done.
...
ライブラリのビルド
C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo>vcpkg install google-cloud-cpp[core,storage]:x64-windows-cxx17

C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo>dir installed\x64-windows-cxx17
 ドライブ C のボリューム ラベルは OS です
 ボリューム シリアル番号は E886-5372 です

 C:\cxx\project\02-gcp-gs\google-cloud-cpp\repo\installed\x64-windows-cxx17 のディレクトリ

2025/10/27  10:37    <DIR>          .
2025/10/27  10:36    <DIR>          ..
2025/10/27  10:37    <DIR>          bin
2025/10/27  10:36    <DIR>          debug
2025/10/27  10:43    <DIR>          include
2025/10/27  10:43    <DIR>          lib
2025/10/27  10:43    <DIR>          share
2025/10/27  10:37    <DIR>          tools
               0 個のファイル                   0 バイト
               8 個のディレクトリ  609,756,209,152 バイトの空き領域

ビルドした google-cloud-cpp を参照

上記で生成されたヘッダとライブラリを参照するようにプロジェクトの設定を変更する。

追加のインクルード・ディレクトリ

$(SolutionDir)google-cloud-cpp\repo\installed\x64-windows-cxx17\include

image.png

追加のライブラリ・ディレクトリ

デバッグ用とリリース用で異なるディレクトリを指定する。

Release $(SolutionDir)google-cloud-cpp\repo\installed\x64-windows-cxx17\lib
Debug $(SolutionDir)google-cloud-cpp\repo\installed\x64-windows-cxx17\debug\lib

image.png

実行時 PATH 環境変数

デバッグ用とリリース用で異なるディレクトリを指定する。

Release PATH=$(SolutionDir)google-cloud-cpp\repo\installed\x64-windows-cxx17\bin

Debug PATH=$(SolutionDir)google-cloud-cpp\repo\installed\x64-windows-cxx17\debug\bin

image.png

ソースコード

エラー処理を除いた最小限の実装。

C:\cxx\project\02-gcp-gs\02-gcp-gs.cpp
#pragma comment(lib, "google_cloud_cpp_storage.lib")
#pragma comment(lib, "google_cloud_cpp_rest_internal.lib")
#pragma comment(lib, "google_cloud_cpp_common.lib")
#pragma comment(lib, "abseil_dll.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "crc32c.lib")
#pragma comment(lib, "bcrypt.lib")

#ifdef _DEBUG
    #pragma comment(lib, "libcurl-d.lib")
#else
    #pragma comment(lib, "libcurl.lib")
#endif

#include <iostream>
#include <fstream>
#include <cassert>

#include <google/cloud/storage/client.h>
#include <nlohmann/json.hpp>

// ファイルの内容を文字列で取得
std::string get_file_contents(const std::string& file_path)
{
    std::ifstream is{ file_path };
    std::stringstream buffer;
    buffer << is.rdbuf();
    return buffer.str();
}

// 鍵ファイル(json) から GCS クライアントを生成
google::cloud::storage::Client createStorageClient(const std::string& json_path)
{
    const auto json_str{ get_file_contents(json_path) };
    auto credentials = google::cloud::MakeServiceAccountCredentials(json_str);

    nlohmann::json json_data{ nlohmann::json::parse(json_str) };
    const std::string project_id{ json_data["project_id"] };
    //std::cout << "project_id: " << project_id << std::endl;

    google::cloud::Options options;
    options.set<google::cloud::UnifiedCredentialsOption>(credentials)
        .set<google::cloud::storage::ProjectIdOption>(project_id);

    return google::cloud::storage::Client{ options };
}

// バケット一覧
void listBuckets(google::cloud::storage::Client& gcsClient)
{
    auto buckets = gcsClient.ListBuckets();

    for (auto&& bucket_metadata : buckets)
    {
        std::cout << bucket_metadata->name() << std::endl;
    }
}

// オブジェクト一覧
void listObjects(google::cloud::storage::Client& gcsClient)
{
    auto objects = gcsClient.ListObjects("cpp-project");

    for (auto&& object_metadata : objects)
    {
        std::cout << object_metadata->name() << std::endl;
    }
}

// アップロード
void putObject(google::cloud::storage::Client& gcsClient)
{
    google::cloud::storage::ObjectWriteStream ows{ gcsClient.WriteObject("cpp-project", "main.cpp") };
    ows << get_file_contents(__FILE__);
    ows.Close();
}

int main()
{
    auto gcsClient{ createStorageClient(R"(C:\cxx\cxx-project_credentials.json)") };

    std::cout << "== listBuckets ==" << std::endl;
    listBuckets(gcsClient);

    std::cout << "== listObjects ==" << std::endl;
    listObjects(gcsClient);

    std::cout << "== putObject ==" << std::endl;
    putObject(gcsClient);

    return 0;
}

実行結果

プロジェクトを実行すると以下の出力が行われる。

== listBuckets ==
cpp-project
== listObjects ==
images/
images/6419115.png
images/6451979.png
== putObject ==
success

同じバケットに対し gsutil ls コマンドで確認した結果。

ubuntu@vm1:~$ gsutil ls
gs://cpp-project/
ubuntu@vm1:~$ gsutil ls -r gs://cpp-project/
gs://cpp-project/main.cpp
gs://cpp-project/images/:
gs://cpp-project/images/
gs://cpp-project/images/6419115.png
gs://cpp-project/images/6451979.png
ubuntu@vm1:~$ gsutil ls -l gs://cpp-project/main.cpp
      2796  2025-10-27T05:43:39Z  gs://cpp-project/main.cpp
TOTAL: 1 objects, 2796 bytes (2.73 KiB)

プログラムの出力と同じであることが確認できる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?