議論/標準入出力/ストリームによる実装/10.初期化手順


Top / 議論 / 標準入出力 / ストリームによる実装 / 10.初期化手順

このページは何か? (by ひげぽん)

まとめ

monapi

staticリンク時

  1. user_start
  2. monapi_initialize_memory
  3. invokeFuncList [ __CTOR_LIST__はこのとき monapi_crt/monapi_implで同一のものを参照 ]
  4. __attribute__( (constructor) ) void monapi_initialize()[ invokeFuncListの呼出しによる ]
  5. user_start_c_impl
  6. main

dynamicリンク時

  1. dllmain
  2. monapi_initialize_memory
  3. invokeFuncList [ __CTOR_LIST__は monapi_implのものを参照 ]
  4. __attribute__( (constructor) ) void monapi_initialize()[ invokeFuncListの呼出しによる ]
  5. user_start
  6. invokeFuncList [ __CTOR_LIST__は monapiのものを参照 ]
  7. user_start_c_impl
  8. main

monalibc

staticリンク時(crtは monapi_crt.o)

  1. user_start
  2. monapi_initialize_memory
  3. invokeFuncList [ __CTOR_LIST__はこのとき monapi/monapi_implで同一のものを参照 ]
  4. 以下の2つの初期化メソッドの呼出順序は保証されないので flag を使って monapi->monalibcとなるようにしている
    1. __attribute__( (constructor) ) void monapi_initialize()[ invokeFuncListの呼出しによる ]
    2. __attribute__( (constructor) ) void monalibc_initialize()[ invokeFuncListの呼出しによる ]
  5. user_start_c_impl
  6. main

dynamicリンク時

  1. dllmain(monapi)
  2. monapi_initialize_memory
  3. invokeFuncList [ __CTOR_LIST__は monapi_implのものを参照 ]
  4. __attribute__( (constructor) ) void monapi_initialize()[ invokeFuncListの呼出しによる ]
  5. dllmain(monalibc)
  6. invokeFuncList [ __CTOR_LIST__は crt/dllmain のものを参照 ]
  7. __attribute__( (constructor) ) void monalibc_initialize()[ invokeFuncListの呼出しによる ]
  8. user_start
  9. invokeFuncList [ __CTOR_LIST__は monapi_crtのものを参照 ]
  10. user_start_c_impl
  11. main

monalibc/crt/crt.cpp も monapi.cpp のようにメモリ初期化についてフラグを参照しなければいけなくなりました。
変更済みです。

libgui

GUI.DLLは monapi-imp に依存している。
monalibcと同じ形式で dllmain で invokeFuncList を呼び、libgui_initialize を __attribute__( (constructor) )で呼びます。

libbaygui

libguiと同様

バグ

monalibc/crt/dllmain.cpp の monalibc_initializeで Stream の初期化をやるといろいろうごかなくなります。
原因がさっぱり分からないのでしばらく寝かせようと思います。

申し訳ないのですがもし可能ならば、inStream/outStream は messages.cpp にあるように必要になったときに初期化するように変更頂けないでしょうか。
→id:shotaro_tsuji

古い情報

 散々はまりまくって、某スレで__CTOR_LIST__ の挙動の違い教えてもらいやっと理解した。
  
 論理的には以下の順序で初期化が行われればOK
 static リンク時
  
    1. malloc/free new/delete用ユーザー空間メモリ初期化
    2. staticリンクされたものの __CTOR_LIST__ で初期化ルーチンを実行
    3. ライブラリ固有の初期化
  
 現実的には全て crt で行う
 dynamic リンク時
  
    1. malloc/free new/delete用ユーザー空間メモリ初期化
    2. dynamiリンクされたものの __CTOR_LIST__ で初期化ルーチンを実行
    3. staticリンクされたものの __CTOR_LIST__ で初期化ルーチンを実行
    4. ライブラリ固有の初期化
  
 1, 2, 4は dllmain で、3はcrtで行う。
 やっかいな部分
  
     * static/dynamic リンクによって動きが異なる
     * メモリ初期化だけに限ってはライブラリ固有の初期化より前に行わなければいけない。(staticなクラスのコンストラクタでnewを使っていたりすることが考えられる。)
     * dllの依存関係
  
 結局どうなったか?
 monapi.cpp (crt)
  
 /*----------------------------------------------------------------------
     entry point for application
 ----------------------------------------------------------------------*/
 extern "C" int user_start()
 {
     if (!monapi_memory_initialized)
     {
         monapi_initialize_memory(64 * 1024 * 1024);
     }
     invokeFuncList(__CTOR_LIST__, __FILE__, __LINE__);
     int result = user_start_c_impl(main);
     invokeFuncList(__DTOR_LIST__, __FILE__, __LINE__);
     return result;
 }
  
 monapi_impl.cpp
  
 extern bool monapi_memory_initialized = false;
 static bool monapi_initialized = false;
  
 extern "C" int dllmain()
 {
     monapi_initialize_memory(64 * 1024 * 1024);
     invokeFuncList(__CTOR_LIST__, __FILE__, __LINE__);
     monapi_memory_initialized = true;
     return 0;
 }
  
 extern "C" __attribute__((constructor)) void monapi_initialize()
 {
     if (monapi_initialized) return;
     monapi_initialized = true;
 }
  
 // if __attribute__((constructor)) doesn't work, use this.
 //static struct MonAPIInitWrapper {MonAPIInitWrapper(){monapi_initialize();}} MonAPI_initializer;
  
 monalibc/crt/dllmain.cpp
  
 extern "C" int dllmain()
 {
     invokeFuncList(__CTOR_LIST__, __FILE__, __LINE__);
     return 0;
 }
  
 extern bool monalibc_initialized = false;
  
 extern "C" __attribute__((constructor)) void monalibc_initialize()
 {
     if (monalibc_initialized) return;
     monapi_initialize();
 //     uint32_t handle;
 //     handle = MonAPI::System::getProcessStdinID();
 //     inStream = MonAPI::Stream::FromHandle(handle);
 //     handle = MonAPI::System::getProcessStdoutID();
 //     outStream = MonAPI::Stream::FromHandle(handle);
     init_stdio();
     monalibc_initialized = true;
 }
  
 // if __attribute__((constructor)) doesn't work, use this.
 //static struct MonalibcInitWrapper {MonalibcInitWrapper(){monalibc_initialize();}} Monalibc_initializer;
  
 問題点
  
 monalibc/crt/dllmain.cppのmonalibc_initialize で inStream等のコードをコメントアウトから戻すと一部のコードが動かなくなる。
  
 順序間違えている?
  
 難しいのう。><

コメント

コメントはありません。 コメント/議論/標準入出力/ストリームによる実装/10.初期化手順?

お名前:

MENU

now: 2

リンク


最新の20件
2018-05-03 2017-09-29 2017-04-25 2017-01-10 2016-12-11 2016-10-04 2016-08-14 2016-06-05 2016-05-29 2016-04-15 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 2843, today: 1, yesterday: 0

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

Last-modified: 2008-03-28 (金) 15:48:03 (3734d);  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.057 sec.