問題タブ [idispatch]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
winapi - ATL で匿名 IDispatch 関数を作成する方法は?
IDispatch から派生し、次のように API に渡すことができるクラスを作成する簡単な方法はありますか (これは C++ です):
値 0 の dispid で呼び出しを処理する C++ オブジェクトを作成する方法は知っていますが、すべての IDispatch を手動で実装するのは常に少し面倒です。かなり一般的であるため、ATLには標準的な方法があるかどうか疑問に思っていました。
c++ - プロトタイプメンバー関数を取得するにはどうすればよいですか (C++ -> Javascript)
C++ から Javascript でプロトタイプのメソッドを呼び出す方法を知っている人はいますか?
スクリプト IDispatch へのポインターがあり、プロトタイプの IDsOfNames を取得できますが、メンバー関数の IDispatch を取得する方法が見つかりません。
言う (擬似コード):
foo の有効な DISPID を取得できますが、呼び出し方がわかりませんbar(baz)
。誰にもアイデアはありますか?
.net - .NET バッキングで IDispatch* を複製する必要があります。クラス名がわからない
完全なリストではありませんが、次の方法を使用して C++ プログラムで .NET ライブラリをホストしています。
.NET クラスに対応する C++ クラスがあります。各クラス インスタンスには が含まれておりCComPtr<IDispatch>
、これを使用して関数を呼び出し、メンバー変数を取得/設定します。
これは正常に機能していますが、C++ クラスをコピーすると、最終的に 2 つの C++ クラス インスタンスが同じ .NET インスタンスを指すことになります。あるインスタンスで変数値を変更すると、別のインスタンスに反映されます。
したがって、各 C++ クラス インスタンスが 1 つの一意の .NET クラス インスタンスを持つように、IDispatch ポインターを複製したいと考えています。を呼び出すことはできますCreateInstance()
が、さまざまな理由から、ライブラリとクラスの名前を把握するのは不便です。
tl;dr
クラス/ライブラリ名を検索せずに、.NET でサポートされている IDispatch ポインターを複製するにはどうすればよいですか?
ありがとう!
com - Excel.Application に IDispatch.GetTypeInfo() を使用すると Visual Studio IDE がクラッシュする
COM コンポーネントとやり取りするアプリケーションを作成していますが、Visual Studio 10 IDE でアプリケーションを実行しているときに Excel.Application コンポーネントを操作しているときに問題が発生しました。致命的なメモリ不足エラーが発生しています。EXE を実行するだけですべてが正常に動作しますが、デバッグ機能が大幅に制限されます。この方法でアクセスした他のすべての COM コンポーネントは、自家製のコンポーネントと市販のコンポーネントの両方を含め、正常に動作します。
このクラッシュを示すコンソール アプリを次に示します。簡単にするために、すべてのエラー処理を削除しました。問題のあるコードの周りに try/catch ブロックを配置しても役に立ちません。このプロジェクトには、CustomMarshalers.dll への参照が必要です。
問題は単に Excel のサイズによるものだと思います。
winapi - CreateStdDispatchは、呼び出すメソッドをどのように認識しますか?
私はIDispatch
インターフェースの実装に直面しています。4つの方法があり、幸い3つは簡単です。
それが最後の方法です、Invoke
それは難しいです。ここで、実際にDispIDをケースに入れて、適切なメソッドを呼び出す必要があります。バリアント配列からのパラメーターのマーシャリング解除。
面倒な定型コードをすべて書く必要はなく、バグがあると確信しているので、作業を行うのではなく、グーグルで調べました。
私はこのスニペットをMSDNドキュメントでIDispatch.Invoke
見つけました:
通常、 Invokeを直接実装しないでください。
素晴らしい!とにかくそれを実装したくありませんでした!続きを読む:
代わりに、ディスパッチインターフェイスを使用して、関数CreateStdDispatchおよびDispInvokeを作成します。詳細については、CreateStdDispatch、DispInvoke、IDispatchインターフェイスの作成、およびActiveXオブジェクトの公開を参照してください。
IDispatchインターフェイスの作成リンクには次のように記載されています。
IDispatchは、次のいずれかの方法で実装できます。
- [をちょきちょきと切る]
- CreateStdDispatch関数を呼び出します。このアプローチは最も単純ですが、豊富なエラー処理や複数の国語を提供していません。
- [をちょきちょきと切る]
すばらしい、CreateStdDispatchは次のとおりです。
単一の関数呼び出しを介してIDispatchインターフェースの標準実装を作成します。これにより、自動化によるオブジェクトの公開が簡単になります。
私はそれを次のように呼ぶつもりでした:
私が理解できないのは、Windows APIの実装がCreateStdDispatch
、オブジェクトで呼び出すメソッドをどのように知っているかです。特に、CreateStdDispatch
使用しているオブジェクト指向言語やその呼び出し規約がわからないためです。
どうやっCreateStdDispatch
て知るのか
- 特定のメソッドを呼び出す方法は何
dispid
ですか? - 私の言語の呼び出し規約?
- オブジェクト指向オブジェクトが書かれている言語からの例外を処理する方法は?
注:私はdispinterface
;を実装する以外に選択肢はありません。私はインターフェースを定義しませんでした。私はそれが単純な早期の限界IUnknown
であったことを望みます、しかしそれはそうではありません。
javascript - DISPID_NEWENUMを使用してC++でjavascript配列オブジェクトを取得するとIE9で失敗します
しばらく前に答えた同様の質問に続いて、オブジェクトを列挙しようとすると、IE9での使用IDispatch::Invoke(DISPID_NEWENUM,...)
が失敗することがわかりました。
これは、任意のjavascript配列のおよびで発生します。DISP_E_EXCEPTION
IDispatch
IDispatchEx
言うまでもなく、このコードはIE6-IE8でうまく機能し、IE9でのみ失敗します。
同じ質問がMSDN開発フォーラムにも表示されますが、これまでのところ運がありません。
これが私がやろうとしたことを示すためのコードスニペットです。pDispatch
これがjavascriptの配列バリアントであることに注意してください。
特にIE9でDISP_E_EXCEPTIONのHRESULTを使用して、このコードが常に失敗する理由(IDispatchおよびIDispatchEx)を誰かが知っていますか?
ありがとう。
c++ - IDispatch オブジェクトへのすべての参照が解放されないのはなぜですか?
プレーンな Win32 (mfc、atl、wtl などなし) のみを使用して、C++ プログラムで IWebBrowser2 コントロールをホストしています。DISPID_NAVIGATECOMPLETE2 で、表示された Web ページで実行されている JavaScript からアクセスされるカスタム オブジェクトを追加します。
カスタム オブジェクトを追加するには、DISPATCH_PROPERTYPUT と、カスタム オブジェクトへのポインターを指定した DISPPARAMS 構造体を指定して InvokeEx を呼び出します。
InvokeEx の呼び出し中に、カスタム オブジェクトの AddRef 関数が呼び出され、その参照カウンターをインクリメントします。ただし、オブジェクトがその Release 関数を呼び出すことはないため、参照カウンターが再びゼロになることはありません。
InvokeEx で AddRef() が呼び出された後、Release() を呼び出すのは誰の責任ですか?
編集:(いくつかのコードを追加)
これは、カスタム オブジェクトを IHTMLWindow2 に追加するコードです。custObj
カスタムオブジェクトを指す
これは私が追加しているオブジェクトです (簡潔にするために一部のプライベート メンバーは省略されています)。
編集2:
正常に動作しているように見えるので、github に置くことにしました。
https://github.com/Tobbe/CppIEEmbed . 可能であればフォークして改善してください:)
c++ - C++ DispInvoke がメンバーを見つけられない
シナリオは次のとおりです。
- 質問するための COM オブジェクトがあります。名前はアイコム。
- COM オブジェクトでは、イベントを通知する IComEvents の子孫である IDispatch を実装する必要があります。
- IDispatch を実装し、それを COM インターフェイスに接続します。
ここまでは順調ですね。イベントが発生すると、私の IComEvents 子孫の Invoke() が呼び出されます。
ポイントは、Invoke() パラメーターを手動で解析する必要があるということです。たとえば、通知関数が HRESULT OnMouseHit(int x) の場合、DispID からこの関数を検出し、手動で呼び出す必要があります。
実装したいすべての機能に対してそれを行う必要があります。ただし、おそらく自動的にこれを実行し、適切なパラメーターを使用して dispId の適切なオーバーロードされたメソッドを呼び出す DispInvoke() 関数を見ました。
m_ptinfo を生成するにはどうすればよいですか? COM オブジェクトの libid を指定して LoadRegTypeLib を呼び出し、次に IComEvents の IID を指定して ITypeLib::GetTypeInfoOfGuid() を呼び出します。ただし、DispInvoke() は常に「メンバーが見つかりません」を返します。
何が間違っているでしょうか?DispInvoke が型情報を解析し、DispID からメンバー関数名を見つけてから、「this」ポインターを使用して vtbl から関数アドレスを取得することを期待しています。
私は何を間違っていますか?
どうもありがとう。マイケル。
windows - 解放された COM オブジェクトで呼び出しを呼び出す
アプリケーションの自動化タスクに使用される COM オブジェクトを作成します。これが発生すると、アプリケーションが起動され、そのメイン ウィンドウが表示されます。
この問題は、ユーザーがメイン アプリケーション ウィンドウを閉じたときに発生します。COM オブジェクトへの Next Invoke 呼び出しが機能しません。問題は、失敗せず、エラーを報告しないことです。コードの次の行にデバッガーのブレークポイントを配置すると、到達することはありません。Invoke 呼び出しを try/catch で囲むと、例外はキャッチされません。リリースビルドではクラッシュするだけです。
これはどのように機能するはずですか?私は CComDispatchDriver を IDispatch* のラッパーとして使用しているので、ユーザーがアプリケーションを閉じても、AddRef が COM オブジェクトを存続させると期待できます。少なくとも HRESULT をエラーとして取得することを望んでいました。
delphi - XE2 で IDispatch をキャストするアクセス違反
古いコード (Binh Ly によって作成された ComLib.pas) を使用しているため、(OleVariant) オブジェクトで列挙型インターフェイスを使用できます。
このコードは、Delphi 2010 および 2007 では機能しますが、XE2 では機能しません。上記の行 (コメント「RAISES EXCEPTION」を含む) で、例外が発生します。
プロジェクト x.exe は例外クラス $C0000005 を発生させ、メッセージ「0xbaadf00d でのアクセス違反: アドレス 0xbaadf00d の読み取り」が発生しました。
渡されたオブジェクトには TDispNewEnum インターフェイスがあるため、例外は発生しません(Delphi 2010 および 2007 の場合と同様)。
提案?ありがとう。