さて、今日はフリーソフトウェアのライセンスについてのお話です。
- このソフトウェアを誰でも無償で無制限に扱って良い。ただし、著作権表示および本許諾表示をソフトウェアのすべての複製または重要な部分に記載しなければならない。
- 作者または著作権者は、ソフトウェアに関してなんら責任を負わない。
さて、今日はフリーソフトウェアのライセンスについてのお話です。
どうも。お久しぶりです。
さて、今日はC++のluabindについての記事になります。
luabindについては「こちら」をご覧ください。
実は先ほどまでluabindと格闘しておりました。orz
正確には「luabind::nil」と格闘してました。
――というのも、Luaのnilについて、「Lua側から取得した結果、nilでした。」
――というのは取れるが、C++側から任意にnilを設定する事が出来ません。
Google先生に聞いて、色々と調べてみましたが、記事らしい記事を見つけられず、半ば諦めかけていました。
とりあえず、luabind名前空間に何か無いか漁っていた所、「nil」という変数があるのを見つけたので、適当に以下のコードで「luabind::object」にセットするよう書いたのですが・・・
#include <lua.hpp>
#include <luabind/luabind.hpp>
lua_State* test_state = luaL_newstate();
luabind::object test_obj1;
luaL_openlibs(test_state);
luabind::open(test_state);
test_obj1 = luabind::object(test_state,luabind::nil);//nil代入テスト
if ( luabind::type(test_obj1) == LUA_TNIL ) { OutputDebugString("nilですよ!"); }
test_obj1 = luabind::object();
lua_close(test_state);//Luaを閉じる。
test_state = NULL;//念のため。
ビルド後、実行すると「nil代入テスト」の行でstd::runtime_errorになってしまいました。
停止行付近にあった、std::runtime_errorに渡しているエラー文字列を確認した所、「未登録のクラスを使用しようとしています」書かれており、「luabind::nil」自体が「luabind::detail::nil_type」構造体なのですが、どうも、luabind側で対応していないようです。(馬鹿なの?)
結局、色々調べてluabind内で使用している、テンプレートクラス「luabind::default_converter」を追加定義すればいけそうだったので、
以下のようなテンプレートの追加オーバーロード定義を行いました。
【NilConverter.h】
#ifndef INCLUDE_20190310_A655SUSXT4JY
#define INCLUDE_20190310_A655SUSXT4JY
#include <lua.hpp>
#include <luabind/luabind.hpp>
namespace luabind{
template <>
struct default_converter <luabind::detail::nil_type>
: native_converter_base<luabind::detail::nil_type>{
static int compute_score( lua_State* L , int index ) {
switch ( lua_type( L , index ) ) {
case LUA_TNIL:
return 0;//対応する型の場合は「0」を返せば良いっぽい。
default:
return -1;//未対応の型は「-1」にするっぽい。
}
}
luabind::detail::nil_type from( lua_State* L , int index ) {
return luabind::nil;
}
void to( lua_State* L , luabind::detail::nil_type const& value ) {
lua_pushnil(L);
}
};
template <> struct default_converter<luabind::detail::nil_type const > : default_converter<luabind::detail::nil_type>{};
template <> struct default_converter<luabind::detail::nil_type const&> : default_converter<luabind::detail::nil_type>{};
}
#endif//INCLUDE_20190310_A655SUSXT4JY
これを最初にランタイムエラーになってしまったコードに対して、
インクルードするようにします。
#include "NilConverter.h"
lua_State* test_state = luaL_newstate();
luabind::object test_obj1;
luaL_openlibs(test_state);
luabind::open(test_state);
test_obj1 = luabind::object(test_state,luabind::nil);//nil代入テスト
if ( luabind::type(test_obj1) == LUA_TNIL ) { OutputDebugString("nilですよ!"); }
test_obj1 = luabind::object();
lua_close(test_state);//Luaを閉じる。
test_state = NULL;//念のため。
※変更箇所は赤表記になってます。
後はこれをもう一度ビルドして実行するだけです。
実際に実行してみた所、ランタイムエラーにならず、「出力」ウィンドウに「nilですよ!」が表示されました!
とはいえ、まさかluabind内に標準定義されている物が使えないとは思いもよらなかったです。(もしかしたら違う使い方を想定していたのかも知れませんが。)
ともあれ、これでLuaとC++双方でnilのやり取りが出来るようになったので、よしとしましょう!(`・ω・´)b
さて、今日はC/C++のビットフィールド構造体とメモリへの
マッピングについて書いておきます。
まず、ビットフィールド構造体とは以下のような物を言います。
struct BitData { uint8_t sample_bit0 : 1;//ビットフィールド1 uint8_t sample_bit1 : 1;//ビットフィールド2 uint8_t sample_bit2 : 1;//ビットフィールド3 uint8_t sample_bit3 : 1;//ビットフィールド4 uint8_t sample_bit4 : 1;//ビットフィールド5 uint8_t sample_bit5 : 1;//ビットフィールド6 uint8_t sample_bit6 : 1;//ビットフィールド7 uint8_t sample_bit7 : 1;//ビットフィールド8 };
上記の例の場合、この構造体はメモリ上で1byteの容量を占有します。
この構造体を確保済みのメモリにポインタでマッピングを行なう場合に
注意をする点があったので、メモとしてここに書いておきます。
通常、構造体の並びを決めてその構造体の内容をそのまま保存して呼び出すといった、自分でデータ構造の仕様を決めている場合は特に意識する事もないのですが、
他の人が作成したファイルの読み書き仕様に沿って読み書きを行なう場合には以下の点に注意する必要があります。
どういうことかというと、例えば最初に示した「BitData」構造体を例にすると、
uint8_t sample_bit0 : 1;//ビットフィールド1 uint8_t sample_bit1 : 1;//ビットフィールド2 uint8_t sample_bit2 : 1;//ビットフィールド3 uint8_t sample_bit3 : 1;//ビットフィールド4 uint8_t sample_bit4 : 1;//ビットフィールド5 uint8_t sample_bit5 : 1;//ビットフィールド6 uint8_t sample_bit6 : 1;//ビットフィールド7 uint8_t sample_bit7 : 1;//ビットフィールド8
↑が仕様書で指示された並びだったとする。
この場合、構造体に落としこむ時、構造体の定義を以下のようにする必要がある。
struct BitData { uint8_t sample_bit7 : 1;//ビットフィールド8 uint8_t sample_bit6 : 1;//ビットフィールド7 uint8_t sample_bit5 : 1;//ビットフィールド6 uint8_t sample_bit4 : 1;//ビットフィールド5 uint8_t sample_bit3 : 1;//ビットフィールド4 uint8_t sample_bit2 : 1;//ビットフィールド3 uint8_t sample_bit1 : 1;//ビットフィールド2 uint8_t sample_bit0 : 1;//ビットフィールド1 };
理由はまじめに調べていないが、
おそらく、バイトオーダーに起因する物だと思われる。
今回は一般的なリトルエンディアン環境でコーディングを行なっていたので、
8bit毎に反転させる必要があったが、もし、ビッグエンディアン環境で動かす場合は反転させる必要が無いので、この場合は予め、「#define」マクロで各環境に応じて切り替えられるように作成しておく必要があるかもしれない。
余談だが、この想定で間違い無い場合は自身でデータ仕様を決めてバイナリファイルなどを扱う場合でも「#define」マクロで各環境に応じて切り替える必要が
出てくると思うので、注意したほうがいい。
本ブログ上部の開発状況リストにて、開示していた、「ROエミュ鯖『PhantasmCapitalServer』」につきまして、正式に破棄が決まりましたので、お知らせします。
もう7年も前の物になりますが、当初は一旦閉鎖した後、開発を予定していましたが、仕事などが忙しく、手をつける機会を失っておりました。
それから7年が経ち、最近になって、当時のスクリプトを掘り出しましたが、手の付けられる状況ではなく、このまま再度運営をしても、問題が発生した時に対処ができないため、もう一度、作り直す事にしました。
結果として本プロジェクト「ROエミュ鯖『PhantasmCapitalServer』」は本日をもって正式に制作破棄扱いとなりました。
当時の協力者及びプレイヤー様につきましては私一個人の気まぐれで開始した、ゲームサーバーにご参加していただき、真にありがとうございました。
まだ何時とは明言できませんが、先にお話した通り、ROエミュ鯖の作り直しを考えております。
このエミュ鯖は最新の Auriga とクライアントを使用して作成する予定です。
本ブログ上部の開発状況リストにて、開示していた、「 ファイル転送プログラム※名称未定 」につきまして、正式に破棄が決まりましたので、お知らせします。
元々、バックアップソフトとして開発予定でしたが、仕様や全容が決まっておらず、他のソフトも多岐に渡り、開発中でしたので、本日をもって、「 ファイル転送プログラム※名称未定 」の制作を破棄することに決定しました。
本開発予定のソフトは正式に発表を行なっていませんでしたので、以上のお知らせのみとさせていただきます。