Skip to content

Latest commit

 

History

History
82 lines (68 loc) · 3.29 KB

embed.md

File metadata and controls

82 lines (68 loc) · 3.29 KB

ファイルを読み込む#embed命令を追加 [P1967R14]

  • cpp26[meta cpp]

このページはC++26に採用される見込みの言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

概要

C++26では、#embedディレクティブが追加される。

これは、バイナリリソースを直接コード内に埋め込む機能を提供する。

これにより、今までは実行時に読み込んでいたファイルなどがコンパイル時点で読み込まれ、実行ファイル内に埋め込むことができるようになる。

仕様

#embedディレクティブによって読み込まれたバイナリは、constexpr unsigned char配列として扱われる。

#include <iostream>

int main() {
  constexpr unsigned char image_binary[] = {
    #embed "image.bin"
  };
  std::cout << std::hex;
  for (unsigned char c : image_binary) {
    std::cout << static_cast<int>(c) << ' ';
  }
  std::cout << std::endl;
}

このプログラムは、image.binをバイナリデータとして扱い、バイト列を出力している。

つまり、下のプログラムのように#embedを使用するとテキストファイルの中身をそのままchar配列に格納していることと同じになる。

int main() {
  constexpr char text[] = { 
    #embed "test.txt"
  };
}

#embedディレクティブは、他にもパラメータを受け付ける。

int main() {
  constexpr unsigned char limited_data[] = {
    #embed "data.bin" limit(1024);
  };
  constexpr unsigned char prefixed_data[] = {
    #embed "data.bin" prefix(0x01, 0x02, 0x03)
  };
  constexpr unsigned char suffixed_data[] = {
    #embed "data.bin" suffix(0xFE, 0xFF)
  };
  constexpr unsigned char safe_data[] = {
    #embed "data.bin" if_empty(0x00)
  };
}

それぞれの変数では、以下のようになっている。

  • limit(1024)では、読み込むバイトサイズを1024byteに制限する。もしファイルサイズが1024byteよりも大きければ、最初の1024バイトのみが読み込まれる。
  • prefix(0x01, 0x02, 0x03)では、data.binの内容の前に0x01 0x02 0x03のバイト列を追加している。
  • suffix(0xFE, 0xFF)では、data.binの内容のあとに0xFE 0xFFのバイト列を追加している。
  • if_empty(0x00)では、data.binがからであった場合、0x00のバイト列を格納している。

また、#embedディレクティブは、複数のパラメータを順不同で組み合わせて指定することもできる。

int main() {
  constexpr unsigned char combined_data[] = {
    #embed "data.bin" limit(1024) prefix(0x01, 0x02) suffix(0xFF) if_empty(0x00)
  };
}

これは、limit(1024)でファイルサイズを1024バイトに制限し、prefix(0x01, 0x02)で先頭バイト列0x01 0x02を追加し、 suffix(0xFF)で末尾0xFFを追加し、if_empty(0x00)で空の場合は0x00を格納することになる。

参照