Squirrel/monasq の変更点



 #setlinebreak(on)
 #topicpath
 ** このページは何か? &size(3){(by [[ひげぽん]])}; [#i2f74878]
 ななしさん提供によるSquirrel移植monasq のページです。
 
 ** ファイル [#sc2b0818]
 #ref(monasq100.zip)
 
 ** アクション [#m51bad0d]
 今後ですが以下のように進めたいのですがいかがでしょう。
 +monasq を最新版BayGUIで動くようにする(Baysideさんにサポートしてもらう)
 +subversionリポジトリのtrunk/contribに取り込む
 +同梱のドキュメントなどをWikiにも転載する(?)
 
 // ↓適宜コメントアウトして使いましょう
 //**経緯
 //**目的
 //**概要
 
 //**未解決な問題
 //**関連ページ
 //#ls2
 
 ** コメント [#oc86496e]
 #pcomment(,1000,below,reply)
 
 
 **C 関数を Squirrel から呼び出す方法についてのメモ [#vf375cc3]
 
 ***(1)C関数をそのまま登録できるケース [#s42bd6aa]
  以下の場合
   引数 :整数値, float, const char*
   戻り値:整数値, float
 
  登録関数に関数ポインタと関数名文字列を渡すだけで Squirrel から使えるようになります(どうしてこれだけで使えるのか深く考えだすと気味が悪くなりますが、裏でテンプレート機構を使って引数の型や数などを判別してるみたいです)。
  Register(v, hNamespace, monapi_file_open, _T("monapi_file_open"));
  なので monapi_file_open(), monapi_file_close() のようにパラメータが単純な関数は、monasq_init_monapi_lib() 内で上記登録関数を呼び出せばOKです。~
 
 ***(2)ラッパー関数を作る必要があるケース [#h9c45175]
  以下のような場合
   引数や戻り値に構造体が使われている
   引数をポインタとして受け取って、内容を書き換える
   その他
 
  Squirrel の仮想マシンは内部スタックをC関数に渡すのですが、ラッパー関数を作るにはその受け渡し機構をある程度理解する必要があります。
  このあたりは独特なので、Squirrel リファレンスマニュアルの『第3章 Embedding Squirrel』の、『スタック』『C関数の作成』あたりをざっと読まないと難しいです。
 
  monapi_file_read(), monapi_file_write() は Squirrelクラスを戻り値/引数に取るため、ラッパー関数が必要です。
  予備知識なしで作るのは無理なので、このページ下の『monapi_file_open等の対応について』を参考にしてください。
 
 ***(3)Squirrel 用クラスを作る場合 [#cb509781]
  基本的には(1)と(2)の組み合わせですが、ややこしいので割愛です。もしクラスを作る場合は、SqSharedMemory クラスを定義/登録している部分が参考になると思います。
 
 
  MonaSq における関数やクラスの登録はほとんどの場面で SqPlus ヘルパーライブラリを使っていますが、この SqPlus のドキュメントやリファレンスは(日本語でも英語でも)今のところ存在しないようです。本家の掲示板のやり取りと、それをまとめたサンプルコードを読むしかないです。なので、あまり深く足を突っ込まない方が無難かも知れません。
 
 
 ** monapi_file_open等の対応について [#r602f0fe]
 monapi_file_read() と monapi_file_write() のラッパー関数の実例です。少し書き直しました。
 現行 MonaADK 上では動かないためテストできていませんが、多分これでいけるはずと思いますー。
 
 monasq_monapi.cpp  520行目あたりに以下を追加
  int wrapper_monapi_file_read(HSQUIRRELVM v) {
     StackHandler sa(v);
     int nargs = sa.GetParamCount(); // 渡された引数の数+1(1つ目の引数には必ず this が渡されるため)
     if (nargs != 3) return 0;       // 引数の数をチェック。スタックに戻り値を積んでいないので0を返す
  
     int id = sa.GetInt(2);          // 引数1
     int prompt = sa.GetInt(3);      // 引数2
     monapi_cmemoryinfo* mi = monapi_file_read(id, prompt);
     SqSharedMemory::push_memoryMap(mi); // 新しい SqSharedMemory オブジェクトを作成してスタックに push
     return 1;                       // スタックに戻り値を1つ積んだので1を返す
  }
  
  int wrapper_monapi_file_write(HSQUIRRELVM v) {
     StackHandler sa(v);
     int nargs = sa.GetParamCount(); // 渡された引数の数+1(1つ目の引数には必ず this が渡されるため)
     if (nargs != 4) return 0;       // 引数の数をチェック。スタックに戻り値を積んでいないので0を返す
     int ret = 0;                    // 戻り値として返す整数値
  
     int id = sa.GetInt(2);                                          // 引数1
     SqSharedMemory* mem = (SqSharedMemory*)sa.GetInstanceUp(3, 0);  // 引数2
     dword size = (dword)sa.GetInt(4);                               // 引数3
     // ↓TRACEマクロは make DEBUG=TRUE で make すると有効になります
     TRACE("wrapper_monapi_file_write() - id:%d sharedMemoryObj:%08x size:%d\n", id, mem, size);
     if (mem) {
         monapi_cmemoryinfo* mi = mem->mi;   //←SqSharedMemory::mi を public に移動しておいてください
         ret = monapi_file_write(id, mi, size);
     }
     return sa.Return(ret);      // スタックに int値を戻り値として積んで戻る
  }
 
 monasq_monapi.cpp  700行目あたりに以下を追加
  RegisterVarArgs(v, hNamespace, wrapper_monapi_file_read, _T("monapi_file_read"));
  RegisterVarArgs(v, hNamespace, wrapper_monapi_file_write, _T("monapi_file_write"));
 
 テストコード(Squirel用)
  local fileID = monapi.monapi_file_open("/AUTOEXEC.MSH", monapi.MONAPI_FALSE);
  local mem = monapi.monapi_file_read(fileId, 486);
  local mem = monapi.monapi_file_read(fileID, 486);
  print("AUTOEXEC.MSH size = 485, readResult size = %d\n", mem.getSize());
  monapi.monapi_file_close(fileId);
  monapi.monapi_file_close(fileID);
 
 **setjmpの件 [#j8a266fe]
 以下のコードで、longjmp() 呼び出し時にハングアップすることを確認しました(現行版のMonaADKにてCUIアプリとしてmakeして実行。ハングアップ時、『ASSERT failure setjmp.cpp』と表示が出ます)。
  #include <monapi.h>
  #include <monalibc/setjmp.h>
  
  jmp_buf g_errorjmp;
  
  int MonaMain(List<char*>* pekoe) {
  
  	if(setjmp(g_errorjmp) == 0) {
  		printf("JUMP\n");
  		longjmp(g_errorjmp, 1);
  	}
  	printf("END\n");
  	return 0;
  }

リロード   新規 編集 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.004 sec.