litediary

<6月 2009年07月 8月>
      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 31  
過去の記事
2015年04月  2015年01月  2014年09月  2014年07月  2014年02月  2013年12月  2013年01月  2012年12月  2012年11月  2012年07月  2012年06月  2012年05月  2012年04月  2012年03月  2012年02月  2012年01月  2011年12月  2011年11月  2011年10月  2011年08月  2011年07月  2011年06月  2011年05月  2011年04月  2011年03月  2011年01月  2010年12月  2010年11月  2010年10月  2010年09月  2010年08月  2010年07月  2010年06月  2010年04月  2010年03月  2010年02月  2010年01月  2009年12月  2009年11月  2009年10月  2009年09月  2009年08月  2009年07月  2009年06月  2009年05月  2009年04月  2009年03月  2009年02月  2009年01月  2008年12月  2008年11月  2008年10月  2008年09月  2008年08月  2008年07月  2008年06月  2008年05月  2008年04月  2008年03月  2008年02月  2008年01月  2007年12月  2007年11月  2007年10月  2007年09月  2007年08月  2007年07月  2007年06月  2007年05月  2007年04月  2007年03月  2007年02月  2006年12月  2006年11月  2006年10月  2006年09月  2006年08月  2006年07月  2006年06月  2006年05月  2006年04月  2006年03月  2006年02月  2006年01月  2005年12月  2005年11月  2005年10月  2005年09月  2005年08月  2005年07月  2005年06月  2005年05月  2005年04月  2005年03月  2005年02月  2005年01月  2004年12月  2004年11月  2004年10月  2004年09月  2004年08月  2004年07月  2004年06月  2004年05月  2004年04月  2004年03月  2004年02月 
C++/CLIメモ managedなmethodをnativeからコールバック その309/07/31 18:51
呼び出し規約の問題は解決した。

あとは可変長引数の問題だ。

 typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
 
こんなやつ。

 SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc);
 
こんな子がいるんだけど

 delegate void SqPrintFunctionDelegate(HSQUIRRELVM, const SQChar*, ...array^);
 void SetPrintfunc(SqPrintFunctionDelegate^ func)
 {
     sq_setprintfunc(_VM,
         (SQPRINTFUNCTION)Marshal::GetFunctionPointerForDelegate(func).ToPointer(),
         (SQPRINTFUNCTION)Marshal::GetFunctionPointerForDelegate(func).ToPointer());
 }

こうしてやっても予想通りだめだ。
実行時にdelegate呼び出しあたりで例外が発生。
まぁ、この引数はprintf形式で来るのでC#に流しても処理できないんだけどね…。
しょうがないので一度unmanagedで受けてvsprintfしてからdelegateに投げてみる。

・HSQUIRRELVMはラップ対象のオブジェクト。中身はポインタ。
・SqVMはHSQUIRRELVMをラップしたクラスで、.NET側に公開したいもの。
・SqVMのインスタンス毎に別のdelegateを登録可能にしたい。
・delegateにはSqVMのハンドルを渡したい。

 #pragma unmanaged
 typedef (*printfunc)(HSQUIRRELVM, const SQChar*);
 static printfunc _printfunc = NULL;

 static void printfunc_adapter(HSQUIRRELVM v, const SQChar* fmt, ...)
 {
     // vsprintfしてbufferにフォーマット済みの文字列を入れる
     _printfunc(v, buffer);
 }

 #pragma managed
 public delegate void SqUserPrintFunc(SqVM^, String^); //これをmanaged側に公開する
 public ref class SqVM
 {
     [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
     delegate void SqApiPrintFunc(HSQUIRRELVM v, const SQChar* str);
     
     static Dictionary^ vms = gcnew Dictionary();
     static SqApiPrintFunc^ pf = gcnew SqApiPrintFunc(api_print_func);
     static void api_print_func(HSQUIRRELVM v, const SQChar* str)
     {
         SqVM^ _this = vms[v];
         _this->printfunc(_this, gcnew String(str));
     }
     
     SqPrintFunc^ printfunc;
     HSQUIRRELVM _VM;
     
 public:
     static void Setup()
     {
         _printfunc = (::printfunc)Marshal::GetFunctionPointerForDelegate(pf).ToPointer();
     }
     SqVM(int stacksize)
     {
         _VM = sq_open(stacksize);
         vms->Add((int)_VM, this);
         sq_setprintfunc(_VM, printfunc_adapter, printfunc_adapter);
     }
     void SetPrintFunc(SqUserPrintFunc^ func)
     {
         printfunc = func;
     }
 };

まずSqVM::Setup()を呼び_printfuncを初期化しておく。
それからSqVMのコンストラクタでvmsに登録し、printfunc_adapterをコールバックに登録。
実行中にprintfunc_adapterがコールバックされると、
_printfuncの関数ポインタを経由してapi_print_funcが呼ばれ、
HSQUIRRELVMをキーにSqVMのハンドルを取り出して個別のprintfuncを呼ぶ
と。

これでユーザからは

 SqVM.Setup();
 SqVM v = new SqVM(1024);
 v.SetPrintFunc(new SqUserPrintFunc(myprintfunc));
 
で登録できるように。

コールバックにvoid* userdataとかを登録できれば
そこに直接呼び出したいdelegateの関数ポインタを登録してやったり出来たんだけど。
出来ないのでちょっとひと手間。

これもAttributeをちょろっと書くだけで解決したりしないんだろうか。
C++/CLIメモ managedなmethodをnativeからコールバック その209/07/30 16:57
__stdcallをつけないと吹っ飛ぶと書いた。
つけれるなら、まぁそれで良いんだ。

問題はそこを変更できない場合で、既存のものからコールバックしてほしいときは__stdcallつけるわけにはいかない。

.NET 1.1まではまともな手段ではどうしようもなかったようで、
http://www.codeproject.com/KB/dotnet/Cdecl_CSharp_VB.aspx
このようなものが作られていた。

3.5に組み込んでみたところ、Runtimeエラーだ。
ソース読んでみるとリフレクションで.NET Framework内部のprivate/internalなメソッドをいろいろ呼んでいて、そこが変更されて動かなくなってるようだ。
まぁそんなことしてたらバージョン替わって動かなくなっても文句は言えない…。

んでそこのフォーラムを読んでみたら、
.NET Frameowrk 2.0以降はもっと簡単に

 typedef void (__cdecl *CallbackFunc)(int);
  :
 [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
 delegate void simpleFunc(int);
  :

この1行追加でOKのようだ。

あるんじゃないかなぁとは思っていたけど、日本語で情報が見つけられなくて大幅に遠回りしてしまった。
たしかに上記アトリビュートをMSDNで調べると、ちゃんと日本語で書いてあるんだけど、そこまでの道が無かった。
C++/CLIメモ managedなmethodをnativeからコールバック09/07/29 20:02
#pragma unmanaged
typedef void (__stdcall *CallbackFunc)(int);
void NativeCallback(CallbackFunc func)
{
    func(123);
}

#pragma managed
void ManagedCallback(CallbackFunc func)
{
    func(321);
}
using namespace System;
using namespace System::Runtime::InteropServices;

delegate void simpleFunc(int);
ref class Hoge
{
internal:
    int i;
    void memberFunc(int n) { Console::WriteLine("memberFunc {0} {1}", i,n); }
    static void staticFunc(int n) { Console::WriteLine("staticFunc {0}", n); }
};

int main(array^ args)
{
    Hoge h1;
    h1.i = 1234;
    simpleFunc^ func = gcnew simpleFunc(%h1, &Hoge::memberFunc); // thisも渡せる。
    func += gcnew simpleFunc(Hoge::staticFunc); // もちろんstaticなmethodも渡せる。

    // 直接delegateを呼んでみる
    func(111);
    // managedな関数に関数ポインタ形式で渡して呼んでみる
    ManagedCallback((CallbackFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer());
    // nativeな関数に関数ポインタ形式で渡して呼んでみる
    NativeCallback((CallbackFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer());
    return 0;
}

----------------

typedef void (__stdcall *CallbackFunc)(int);
__stdcallが重要。
無いとふっとぶ。
たまに動いてしまう事もあるからたちが悪い

simpleFunc^ func =
funcを保持しておかないと、GCに回収されてコールバックしようとしたときにはdelegateが無いなんてことになる。
今回のサンプルならその場でしかコールバックされないが、
タイマーのようにあとからコールバックされるときなんかは注意。

TDF200909/07/09 04:10
ツール・ド・フランスは100年以上の歴史を持つロードレースの世界最大の大会で、
これまで日本人は数人が出場しただけでした。
今年は日本人が二人出場ということで、日本でも多少注目度が上がってる…のかな?
最近は自転車ブームですしね。
そういう自分も去年くらいから観はじめたんだけど。

今年は7/4から7/26日まで。
動画はこちらから。
http://www.nicovideo.jp/mylist/13414621
去年のもこのひとの動画で観たんだけど、適度にまとまってていい感じ。
フルで見ると長すぎるので…。
(マイリストは私が見た分を追加してるものなので、更新は少し遅れます)

で、やっぱこういうのをみると、自分も走りたくなるわけですよ。
それで昨日は寝る前に腹筋をしたんですよ。10回。
そしたら筋肉痛に…
これはひどい。
まぁ今日もなんとか腹筋10回/背筋15回/腕立て10回。
明日は動けないかもしれんね。

自転車も乗ってやらないとなぁ。
20万↑のロードを買ってまだ500kmくらいしか走っていない。
でも、これからの季節は暑いので秋から頑張る。


以下はネタバレを含むので、これから観る人は読まないように。
見る気無い人は読んでもOK。
で、もし面白そうだと思ったら動画のほうも見てもらえれば。


第1ステージはTT(タイムトライアル)。
まぁ普通でした。
TTは個人の実力勝負で、駆け引きやスピード感がいまいちなので見てるほうとしては眠くなりがち。

第2ステージはマスドレース(普通のロードレース)。
ここでいきなり新城が5位。
日本人でステージ一桁順位は始めて。(総合では完走無し)
しかも、ゴールスプリントではトップの後ろにつく形じゃなくて、
ラインはずしてさらに前を狙うポジションでのゴール。
これはすごい。

第3ステージもマスドレース。
今度は別府が8位。
日本人連続とかすごい。
しかもロードレースとして良い仕事をしての8位なので、かなり評価できる。
そしてさりげなく、ランス・アームストロングが総合3位に。

第4ステージはTTT(チームタイムトライアル)
ツールではTTTは4年ぶりらしい。
これは熱い戦い。
マスドレースってのは速ければ勝ちではないので、時にはゆっくり走るけど、TTは完全なスピード勝負。
さらにTTTだと空気抵抗が分散してすごいスピードが出る。
綺麗な隊列ですごいスピードで走るのは圧巻。
そしてランスが総合でトップとコンマ秒差で2位。
復帰していきなりこれとは…。
半分以上一人で牽いてランスから逃げ切った総合トップのカンチェラーラもすごい。
minibbs - テスト稼動中
creeper2012/05/03 01:28
.jpからもきてるんか…
creeper2012/05/02 10:52
誰も書き込まないのにSPAMばっかりくるようになったのでhost名制限かけました。
基本的に逆引きできて*.jpにならないと弾きます
wataru2010/12/01 11:43
GT5俺がかわりにやっといてあげますよ。
q2010/12/01 10:35
消化不良すぎ
2010/10/30 01:03
netbeansだとmakeファイル使う機会があるかもしれませんね
2010/10/05 06:04
なに書き込み不可能とか直しちゃってるのこわい
creeper2010/10/04 02:58
長いことコメント書き込み不可能になってた。直しました。
ao 2007/09/30 10:54
お、良いねぃ
creeper2007/09/16 05:18
そこまで詳しくなかったので調べてみた。Wikipedia万歳
なるほど、失敗する6号機まではかぐやと同じ3t強をSBB無しの202で上げてたんですね。
SRB-Aの出力を下げてSBB追加することでとりあえず対応していたと。

今後の予定をみると、次の燃えるのは2010年の金星探査機かー
「超高速インターネット衛星WINDS」は名前には惹かれるけど都心に引きこもってる限り関係ないなー
Wikipediaの予定だとWINDSは2024になってますね。
重量的に、2024か204か新型か…
A責ダッシュ!2007/09/15 10:11
SSB使っての打ち上げって今回が最後じゃなかったかな?
まー、今回のもSRB-Aがもともとの性能を出せてれば2022じゃなくて202で上げられたかもしれないです。LE-7Aの再生長ノズルはこなれてきたようなので、元のSRB-Aが復帰すればまたちょっとづつ色々変わっていくんじゃないのでしょうか。H-IIBも控えてますしね。
creeper2007/09/12 05:55
http://lovelove.rabi-en-rose.net/blog.php?n=256

今回はcygwinのgccつかってます。
まぁ、ソース見ての通りこの問題が1:1になるのは自明で、
かつrandの結果は偶数奇数が交互に出るようなこともなく、
おかしな偏りも無かったのでOKということで。