Invokeを使ってイベントを発生させるとAccess violation が発生

[戻る]
396 2009/10/04(日) 04:52:38
IWebBrowser を使って HTML を表示しています。
そのHTML に大して Invokeを使ってイベントを発生させると

そのHTMLからget_Scriptで取得したIDispatchExをQueryInterfaceしたときに
Access violation が発生してしまいます。

回避するためにはどうしたらよいのでしょうか?

VisualStudio 2008 で開発しています。
ご教授お願いいたします。

subaru 2009/10/05(月) 17:09:44
>IWebBrowser を使って HTML を表示しています。
>そのHTML に大して Invokeを使ってイベントを発生させると

ここでいうイベントとは具体的に何のイベントのことを言っていますか?
イベントの発生とget_Scriptするタイミングの関係もわかりません。
#InvokeというのはHTMLElementEventsなどを用意しているという意味ではない?

>そのHTMLからget_Scriptで取得したIDispatchExをQueryInterfaceしたときに
>Access violation が発生してしまいます。

IHTMLDocument::get_Scriptの引数はIDispatch*ですが
そこからQueryInterfaceでIDispatchEx*を取得しているという意味でしょうか?
これだけの情報では具体的にどのような操作を行ったのかわかりませんが、
各操作での戻り値は正常な値を返しているでしょうか?

396 2009/10/06(火) 08:12:40
>ここでいうイベントとは具体的に何のイベントのことを言っていますか?
>イベントの発生とget_Scriptするタイミングの関係もわかりません。
>#InvokeというのはHTMLElementEventsなどを用意しているという意味ではない?

イベントとはコネクションポイントのイベントになります。
DISPID_DOCUMENTCOMPLETE が発生するタイミングで HTMLのget_Scriptから
IDispatchを取得し IDispatchEx を QueryInterface して取得しています。

この取得した IDispatchEx を保持しておいて、定期的に
コネクションポイントのIDispatchをInvoke しています。
そのときに DISPID_DOCUMENTCOMPLETE で保持しておいた IDispatchExで 
QueryIntarface を実行しています。
そのときに Access violation が発生してしまいます。

デバッガを使って一つ一つ追っていくと Access violation が発生していないようで
す。

subaru 2009/10/06(火) 12:18:33
>イベントとはコネクションポイントのイベントになります。
>DISPID_DOCUMENTCOMPLETE が発生するタイミングで HTMLのget_Scriptから
>IDispatchを取得し IDispatchEx を QueryInterface して取得しています。

これは DWebBrowserEvents2 の実装を用意して
IWebBrowser2::Navigate2 などを呼んでいるわけですね。

>この取得した IDispatchEx を保持しておいて、定期的に
>コネクションポイントのIDispatchをInvoke しています。
>そのときに DISPID_DOCUMENTCOMPLETE で保持しておいた IDispatchExで 
>QueryIntarface を実行しています。
>そのときに Access violation が発生してしまいます。

これはもう一度ページを遷移させて DISPID_DOCUMENTCOMPLETE イベントの
タイミングで QueryIntarface しているということでしょうか?
DWebBrowserEvents2::Invoke を直接呼んでいるようにも読めるけど
通常はそのような使い方はしないと思います。
どちらにしても Access violation を再現することはできないようですが・・・

396 2009/10/07(水) 01:45:28
>これはもう一度ページを遷移させて DISPID_DOCUMENTCOMPLETE イベントの
>タイミングで QueryIntarface しているということでしょうか?
>DWebBrowserEvents2::Invoke を直接呼んでいるようにも読めるけど
>通常はそのような使い方はしないと思います。
>どちらにしても Access violation を再現することはできないようですが・・・

DISPID_DOCUMENTCOMPLETE が発生するたびに QueryIntarface を実行しています。
Invokeは 自分が用意したコネクションポイントのイベント Fire_Hoge()
の中で呼んでいます。

DISPID_DOCUMENTCOMPLETE で、コネクションポイントのイベントを使用
できるように登録し 100msごとに Fire_Hoge() を呼ぶようにして
試したりもりしていました。

まだわかっていないのですが、実行直後に発生していたのが
デバッガで追っていくと発生しないということもありました。

また、表示しているHTML内のコードに下記のようなスクリプトを使用するような
記述をしていると発生しないようです。

<script type="text/javascript">
<!--
!-->
</script>

subaru 2009/10/07(水) 12:57:41
何をやっているのか結局理解できなかったのですが、
アクセス違反になる理由は無効なポインタからQueryIntarfaceを呼んでいる
可能性が考えられます。

どこかで戻り値がエラーを返しているのかもしれないし、
条件によって未初期化の状態でアクセスする状態になることがあるのかもしれないし、
意図しないタイミングでオブジェクトをRelese()していることなんかも考えられます。
トレースなどでとにかく問題の箇所を見つけるくらいしか対処方法は思いつきません。。。

古いスレッドには追加発言できません。