mieki256's diary



2024/04/05(金) [n年前の日記]

#1 [prog] 自作スクリーンセーバをLinuxに対応させたい。その2

C++とOpenGLを使った自作スクリーンセーバをLinuxにも対応させようとしているところ。GLFWを使ったデモプログラムとして動かすつもり。

_mieki256/ssp3droadgl

Ubuntu Linux 22.04 LTS (g++ 11.4.0, ld 2.38)上でビルドしようとしたらリンクエラーが出てしまって悩んでしまったけれど。ソースコードに手を入れたら改善した。実行バイナリに埋め込んだpngやjpgを展開させる際、サイズの求め方を変えてみたらエラーが出ない状態になった。

ざっくり説明。

画像バイナリ(.png .jpg)を実行バイナリに含める方法は色々あるけど、今回は ld を使ってバイナリファイルをオブジェクトファイルに変換する方法を選んだ。
$ ld -r -b binary -o sprites.o sprites.png

こうしてできたオブジェクトファイルをリンクしてやることで、実行バイナリの中に画像バイナリを含めることができる。

バイナリファイルを ld でオブジェクトファイルに変換すると、*_start, *_end, *_size の3つのシンボルを、C/C++側から参照できる状態になる。

以下は objdump -x を使って、オブジェクトファイルに含まれている情報をダンプしてみた例。「SYMBOL TABLE:」で、3つのシンボルが ―― *_end、*_size、*_start が並んでることが分かる。
$ ld -r -b binary -o sprites.o sprites.png

$ objdump -x sprites.o
 
 sprites.o:     ファイル形式 elf64-x86-64
 sprites.o
 アーキテクチャ: i386:x86-64, フラグ 0x00000010:
 HAS_SYMS
 開始アドレス 0x0000000000000000
 
 セクション:
 Idx Name          Size      VMA               LMA               File off  Algn
   0 .data         00875cae  0000000000000000  0000000000000000  00000040  2**0
                   CONTENTS, ALLOC, LOAD, DATA
 SYMBOL TABLE:
 0000000000000000 l    d  .data  0000000000000000 .data
 0000000000875cae g       .data  0000000000000000 _binary_sprites_png_end
 0000000000875cae g       *ABS*  0000000000000000 _binary_sprites_png_size
 0000000000000000 g       .data  0000000000000000 _binary_sprites_png_start


C/C++側からこれらのシンボルを利用したい時は、以下のように書いておく。これで各シンボルが参照できるようになる。
extern unsigned char _binary_sprites_png_start; // binary start address
extern unsigned char _binary_sprites_png_end;   // binary end address
extern unsigned char _binary_sprites_png_size;  // binary size


このシンボルを利用して、実行バイナリ内の画像バイナリの展開処理を行うわけだけど…。今までは *_size を使って処理してた(つもりだった)。
        img_ptr = &_binary_sprites_png_start; // start address
        img_size = (size_t)&_binary_sprites_png_size; // size
        gw.spr_tex = createTextureFromMemory(img_ptr, img_size);

これを、end - start でサイズを求めるように修正してみた。
        img_ptr = &_binary_sprites_png_start; // start address
        img_size = (size_t)((&_binary_sprites_png_end) - (&_binary_sprites_png_start)); // size
        gw.spr_tex = createTextureFromMemory(img_ptr, img_size);

このように書き換えてみたところ、エラーが出なくなってビルドが通るようになった。実行バイナリも期待した通りに動作してくれた。

また、この書き換えをしたことで、Ubuntu Linux 20.04 LTS上で発生していた不具合も ―― テクスチャの展開が時々失敗する問題も何故か解決してしまった。何度試しても、必ず展開できる…。もしかして今までは、サイズが不定値になっていたのだろうか…?

以上です。

過去ログ表示

Prev - 2024/04 -
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project