0

WindowsMediaPlayerプラグインの他のプログラマーのソースコードをデバッグしています。このプラグインにより、WMPがクラッシュすることがあり、プラグイン設定ウィンドウを開くのに非常に長い時間がかかることがあります。この問題は、音楽の再生中に設定ウィンドウを開いた場合にのみ発生します。プレイヤーが停止している場合は問題なく開きます。

コードを調べてデバッグしていると、問題の原因と思われるコードの行にたどり着きました。

プロパティページには、次のメンバー変数があります。

CComPtr<IDsp_plugin> m_pDsp_plugin;

初期化時のプロパティページは、COMオブジェクトのget_textメソッドを呼び出します。

unsigned char * txt = NULL;
//m_pDsp_plugin is a valid pointer to IDsp_plugin
HRESULT res = m_pDsp_plugin->get_text(&txt);

現時点では、hresは「0x80010105:サーバーが例外をスローしました」です。Visual Studioのデバッグ出力には、「wmplayer.exeの0x764efbaeでの初回例外:0x80010105:」と表示されます。

get_textメソッドは次のように定義されています。

Dsp_plugin.idlで

interface IDsp_plugin : IUnknown
{
    HRESULT get_text([out] unsigned char* *pVal);
...

Dsp_plugin.hで

class ATL_NO_VTABLE CDsp_plugin : 
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CDsp_plugin, &CLSID_Dsp_plugin>,
    public IDsp_plugin,
    public IMediaObject,
    public IWMPPluginEnable,
    public ISpecifyPropertyPages
{

    STDMETHOD(get_text)(unsigned char* *txt);
...

そして最後に、この例外をスローするメソッド自体:Dsp_plugin.cpp

STDMETHODIMP CDsp_plugin::get_text (unsigned char* *txt)
{
   ... // some code for copying a valid string from somewhere to char* y
   // 11 bytes of memory for y was allocated using malloc(10+1);
   // y contains a valid C string here, tested with debugger and passing to OutputDebugStringA

   *txt = (unsigned char*)(y); // This line executes normally, but at the end the caller gets "The server threw an exception." and WMP starts behaving weirdly. 
                               // If I comment it out, the caller gets S_OK and there are no any issues with WMP.

   return S_OK;
}

COM DLLは、「Unicode文字セットを使用する」設定でコンパイルされます。

私はCOMプログラマーの経験はありませんが、文字列をunsigned char **として渡すことは私には珍しいようです。私は、COMを扱うときに主にBSTRまたはVARIANTを見てきました。

COMの第一人者が説明できるかもしれませんが、なぜこの例外が発生するのか、メソッドをunsigned char ** / malloc/freeの代わりにBSTR*とSysAllocString/SysfreeStringを使用するように変換するだけで修正できるのでしょうか?

4

1 に答える 1

5

簡単に言えば、COMは型のポインタを渡す方法を知りませんunsigned char *デフォルトのマーシャリングルールが適用され(インターフェイス定義でパラメーター属性が指定されていないため)、これを正しく解釈している場合、COMは外部ポインター自体をtxt適切にマーシャリングしますが、文字列ではなく単一*txtのポインターとして扱います。 。 unsigned char

発信者と着信者がたまたま同じアパートにいる場合でも、これは機能する可能性があります。それの音から、彼らはそうではありません。

最も簡単な解決策は、パラメータをaにすることBSTR *です。COMには、BSTR正しく渡されることを保証する特別な処理があります。

于 2011-07-19T21:12:25.437 に答える