« [本] 横溝正史をあまり読んだことがない私には何とも言えないが人によっては横溝正史風味だと評するかも知れない久々に読んだ骨太の本格ミステリ | トップページ | [Ruby] WIN32OLEとWIN32OLE_EVENT »

2007年8月20日 (月)

[Ruby] WIN32OLEオブジェクトとWIN32OLE_EVENTオブジェクト


なんか自分で整理できていない気がするので、書きながら整理してみよう。



WIN32OLEオブジェクト1つとそのイベントに
反応するWIN32OLE_EVENTオブジェクトが1つあったとする。



GCされるときには、




  1. 先にWIN32OLEオブジェクトがGCされる。



  2. 先にWIN32OLE_EVENTオブジェクトがGCされる。




2.の場合には、WIN32OLE_EVENTオブジェクトがGCされると
それ以降、WIN32OLEオブジェクトのメソッドを呼び出しても
イベントを拾うことができない。
だから、WIN32OLEオブジェクトが存在し続ける限り、
WIN32OLE_EVENTも存在し続けた方が良い。
そこで、WIN32OLE_EVENTはGCされないように
win32ole内部のグローバルな配列に追加している。



だが、WIN32OLEオブジェクトが存在し続ける間だけ、
WIN32OLE_EVENTが存在し続ければ良いのだから、
WIN32OLEオブジェクトにWIN32OLE_EVENTオブジェクトの配列を
メンバーとして持たせれば良い。



...ような気がしてきた。



[ruby-dev]の問題は、このグローバルな配列の件とは別で、
次のような問題だったような気がしてきた。



WIN32OLE_EVENTオブジェクトがGCされるとき、
IConnectionPoint->Unadviseを実行して、OLEサーバーに
イベントを送ってこなくていいよと伝える。
OLEサーバーは参照カウントを1つ減らし、
OLEサーバーは、WIN32OLE_EVENT側のReleaseを呼び出す。
WIN32OLE_EVENT(がアロケートした領域)は、OLEサーバーからの
Releaseの呼び出されるまで存在し続けなければならない。
なので、GCのタイミングでWIN32OLE_EVENTの領域をfreeできないのである。



...というのが問題だったんじゃなかったかな。



つまり、WIN32OLE_EVENTのGCのタイミングでは領域をfreeしないで
Releaseが呼ばれたときに領域をfreeしてしまえば良い



...のかな。



いや、逆にWIN32OLE_EVENTオブジェクトがGCされる前にWIN32OLE_EVENT側の
Releaseが呼ばれる場合もあったような...。



ということで、試してみることは、




  1. WIN32OLE_EVENTオブジェクトを保持するグローバル配列を廃止する。



  2. WIN32OLEオブジェクトにWIN32OLE_EVENTオブジェクトを保持する配列のメ
    ンバを追加する。



  3. ole_event_free と EVENTSINK_Releaseのどちらが先に呼ばれるか
    再確認する。(1.と2.の修正がうまくいった上で)



  4. [ruby-dev]の問題の対策を考え直す。




とりあえず、1.と2.を片付けてから 3.と4.だな。


|

« [本] 横溝正史をあまり読んだことがない私には何とも言えないが人によっては横溝正史風味だと評するかも知れない久々に読んだ骨太の本格ミステリ | トップページ | [Ruby] WIN32OLEとWIN32OLE_EVENT »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: [Ruby] WIN32OLEオブジェクトとWIN32OLE_EVENTオブジェクト:

« [本] 横溝正史をあまり読んだことがない私には何とも言えないが人によっては横溝正史風味だと評するかも知れない久々に読んだ骨太の本格ミステリ | トップページ | [Ruby] WIN32OLEとWIN32OLE_EVENT »