Я отлаживаю исходный код какого-то другого программиста плагина Windows Media Player.Этот плагин иногда вызывает сбой WMP, а иногда требуется очень много времени, чтобы открыть окно настроек плагина.Проблема возникает только при открытии окна настроек во время воспроизведения музыки.Он открывается без проблем, если проигрыватель остановлен.
Просматривая код и отлаживая, я пришел к строке кода, которая, кажется, является причиной проблем.
Свойствостраница имеет следующую переменную-член:
CComPtr<IDsp_plugin> m_pDsp_plugin;
и страница свойств при инициализации вызывает метод get_text COM-объекта:
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;
}
DLL-библиотека COM компилируется с параметром «Использовать набор символов Unicode».
Я не опытный программист COM, но передача строк в виде неподписанного символа ** мне кажется необычной, я видел в основном BSTR или VARIANT при работе с COM.
Может быть, некоторые гуру COM могутобъясните, почему это исключение происходит и может ли оно быть исправлено путем преобразования методов к использованию BSTR * и SysAllocString / SysfreeString вместо unsigned char ** / malloc / free?