GDExtensionシンプルに環境構築するよ Pt.5
前回の続き
最後に、前回作ったDLLを、Godotプロジェクトに追加して使えるようにします。
Godotプロジェクトへの追加
Godotプロジェクトにフォルダを作ります。ここでは、GDExBinという名前のフォルダを作りました。
この中に2つのファイルを放り込みます。1つはPt.4で作ったdll。
libgdexample.windows.template_debug.x86_64.dll
です。
もうひとつは、このDLLを取り込むための、.gdextensionファイルです。まず、godot-cppのtestフォルダからコピペします。
<test/project/example.gdextension>です。
この.gdextensionの中身を次のように書き換えます。
[configuration]
entry_symbol = "example_library_init"
compatibility_minimum = "4.1"
[libraries]
windows.debug.x86_64 = "res://GDExBin/libgdexample.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://GDExBin/libgdexample.windows.template_release.x86_64.dll"
[libraries]項目には、macosとかlinuxとか、各環境で使うdllファイルのパスがリストされています。ここでは、windows.*._x86_64以外をばっさり削除して、パス中の<res://bin>を、先ほど作ったフォルダ、<res://GDExBin>に置き換えます。
ちなみに、[configuration]項目の、entry_symbolは、Dependenciesツールで表示された、DLLの公開関数と同じ名前になっています。これが呼ばれるわけです。
Godotエディタに戻ります。エラーが表示されず、何事も無ければオッケーです。
エラーのパターン
Error 126
Can't open dynamic library: H:/GodotSpecTest/GDExBin/libgdexample.windows.template_debug.x86_64.dll. Error: Error 126: 指定されたモジュールが見つかりません。.
core/extension/gdextension.cpp:455 - GDExtension dynamic library not found:
このエラーが出た場合は、DLLの依存関係が解決していません。DLLの使っているDLLや、「使っているDLLが使っているDLL」が見つからない。すべての依存が解決しないDLLは拾われないため、見つからないというエラーになります。
Error 127
Can't resolve symbol example_library_init, error: "Error 127: 指定されたプロシージャが見つかりません。
これはSCons実行時に、カレントディレクトリをマイSConstructがあるフォルダに移動せず実行していると、このエラーが出るようになります。godot-cppの処理の都合だと思います。
ちなみにこの場合、DependenciesツールでDLLの中身をのぞいても、公開関数が何も存在しなかったはずです。たぶん。
Godot上での動作
今回使用したサンプルコード(cpp)は、Exmpleという名前の、Control派生クラスを追加するものです。スクリプトで、Exampleクラスをnewする行を追加してみます。
特に文法のエラーは出ません。
次に、Ctrlを押しながら、コード中の"Example"の文字をクリックして、Exampleのヘルプを表示してみます。
不思議ですね~!
C++で書かれてたはずのクラス定義が、ヘルプで表示されてます。
これがgodot-cppの処理なんですね。Godotエンジン内のGDクラス一覧に追加されたということです。
・各メンバ変数の名前と型(サイズ)、ひいてはクラス全体のサイズ
・各メンバ関数の名前と引数と、DLL内関数への関数ポインタ
これらを登録してるんじゃないかなーと推測してます。
F6キーで実行してみますが、特にエラーでません。
やったね。
残されし謎
サンプルコードのビルドはできたし、それをGodotに取り込むこともできました。
でも結局わからなかったことがあります。
公式ドキュメントのこのページです。
https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/gdextension_cpp_example.html
"Building the C++ bindings"という項があります。これ、godot-cppフォルダにカレントディレクトリを移動したうえで、sconsを実行しています。つまりgodot-cppのSConstructを、直接sconsに実行させています。
// godot-cppに移動して
cd "C:\godot-cpp-godot-4.1.1-stable"
// platformとbitsを付けてscons実行
// ただし、bits=64はUnknownとして無視される
"C:\python-3.12.0-embed-amd64\Scripts\scons.exe" platform=windows bits=64 use_mingw=yes
これでできあがるのは、libgodot-cpp.windows.template_debug.x86_64.aという27MB程度のファイルです。(マイSConstructでマイDLLを作った時もこのファイルは生成されます)
C++バインディングとは何か?
マーシャリング的なもの? いわゆるインポートライブラリ?これをさせる意図は?
必須なのか? 単なる動作確認?
わかりませんでした!
というわけで、GDExtensionの開発環境構築、ここまで。
最後まで読んでいただきありがとうございます~~!
この記事が気に入ったらサポートをしてみませんか?