我正在調試Windows Media Player插件的其他程序員的源代碼。這個插件有時會導致WMP崩潰,有時需要很長時間才能打開插件設置窗口。只有在播放音樂時打開設置窗口才會出現問題。如果玩家停止,它將不會出現問題。C++,COM和傳遞字符串
在查看代碼和調試過程中,我看到了代碼行,這似乎是導致問題的原因。
的屬性頁具有以下成員變量:
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調試輸出顯示「在0x764efbae第一次機會異常在wmplayer.exe: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程序員,但作爲無符號字符**傳遞字符串似乎不尋常的我,我在處理COM時看到大多數BSTR或VARIANT。
也許一些COM大師可以解釋爲什麼會發生這種異常,並且可以通過將方法轉換爲使用BSTR *和SysAllocString/SysfreeString而不是unsigned char **/malloc/free來解決這個問題?