Привет Народ!
У меня сложилась следующая проблема. Есть out-of-process сервер COM (выполнен в exe-шнике) pmpC4PM.pmpCPMPostProcessor.1
Работает все в следующем скрипте на JScript:
var pmpost = new ActiveXObject("pmpC4PM.pmpCPMPostProcessor.1");
pmpost.Hello();
var xml_cldata = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");
xml_cldata.setProperty("NewParser",true);
xml_cldata.setProperty("SelectionLanguage","XPath");
xml_cldata.setProperty("SelectionNamespaces", "xmlns=''");
var cxm_path = "D:\\projects\\dicc00218\\pmpost\\sys\\exec\\test_drill.cxm";
var fso = new ActiveXObject("Scripting.FileSystemObject");
var cxmfile = fso.OpenTextFile(cxm_path, 1); // 1 - for readingvar cxmtext = cxmfile.ReadAll();
cxmfile.Close();
xml_cldata.loadXML(cxmtext);
// здесь selectSingleNode РАБОТАЕТ !!!!var sss = xml_cldata.selectSingleNode("/PROGRAM");
WScript.Echo(sss.nodeName);
pmpost.OptionFile = "D:\\projects\\dicc00218\\pmpost\\sys\\exec\\Fanuc.pmopt";
pmpost.SourceFileDocument = xml_cldata;
Однако внутри COM объекта selectSingleNode отказывается работать
STDMETHODIMP pmpPMPostProcessor::put_SourceFileDocument(IDispatch* a_p_idisp)
{
HRESULT hr;
a_p_idisp->QueryInterface(
MSXML2::IID_IXMLDOMDocument2,
(void**)&m_cp_xml_doc);
//////////////
CComPtr<MSXML2::IXMLDOMNode> m_comptr_current_node;
// ЭТО НЕ РАБОТАЕТ !!!
hr = m_cp_xml_doc->selectSingleNode(L"/PROGRAM",&m_comptr_current_node);
// ЭТО РАБОТАЕТ!!!
BSTR bstr_xml;
m_cp_xml_doc->get_xml(&bstr_xml);
//////////////return hr;
}
Возможно это какие-то проблемы с маршаллингом... Помогите, пожалуйста, кто может!
Заранее спасибо!
Re: selectSingleNode не работает в out-of-process COM сервер
Здравствуйте, Tom, Вы писали:
>> hr = m_cp_xml_doc->selectSingleNode(CComBSTR(L"/PROGRAM"),&m_comptr_current_node); // Строка должна быть BSTR
Спасибо большое! Это действительно помогло. Скорее всего XML Document требует полноценно выделенной BSTR для работы в out-of-process. Тем не менее в in-process серверах все может работать и с WCHAR константами. В любом случае большое спасибо, на будущее учтем...
Re[3]: selectSingleNode не работает в out-of-process COM сер
Здравствуйте, IKE, Вы писали:
IKE>...XML Document требует полноценно выделенной BSTR для работы в out-of-process. Тем не менее в in-process серверах все может работать и с WCHAR константами.
С чего бы это? BSTR не взаимозаменяем ни с LPOLESTR, ни с LPWSTR. Это все происки С++ников, а не СОМщиков.
Здравствуйте, IKE, Вы писали:
IKE>Здравствуйте, Tom, Вы писали:
>>> hr = m_cp_xml_doc->selectSingleNode(CComBSTR(L"/PROGRAM"),&m_comptr_current_node); // Строка должна быть BSTR
IKE>Спасибо большое! Это действительно помогло. Скорее всего XML Document требует полноценно выделенной BSTR для работы в out-of-process. Тем не менее в in-process серверах все может работать и с WCHAR константами. В любом случае большое спасибо, на будущее учтем...
Всё намного проще. Ты передаёшь строку за пределы апартамента, да ещё и в другой процесс, соответственно применяется маршалинг. В строке BSTR перед её началом хранится её размер, чего нет в обычных C строках. По этому твоя строка нормально не маршалилась в другой процесс. Внутри процесса это работало, так как маршалинга не было, но в нек. случаях это могло и не работать.
Tom>Внутри процесса это работало, так как маршалинга не было, но в нек. случаях это могло и не работать.
ЗЫ А самое гадское, что смарт-оболочки, генерируемый директивой import (tli-файлы) работают с _bstr_t, в который действительно можно передавать OLE-строки.
Здесь Data1 и Data2 имеют идентичный смысл — передача нескольких символов, а Data3 — обычный, т.е. передача единственного символа. То же справедливо и для CHAR, TCHAR, OLECHAR и т.п. типов.
Для BSTR ситуация немного другая, т.к. нет простого типа, который передает этот "указатель". Можно считать в СОМе, что BSTR — это не указатель, а полноценный тип данных — строка.
Во-вторых, для имен BSTR, LPWSTR, LPSTR и т.п. уже определены способы их маршаллинга, так что, я думаю, все атрибуты для таких имен будут просто игнорироваться. Кроме того, маршаллингом BSTR занимается специальные функции BSTR_UserXXXX, ссылки на которые можно увидеть в сгенеренном MIDLом файле.
Во-третьих, [string] — это атрибут, подобный [size_is] etc. только со специфическим определением аргументов, и точно также как и [size_is] не представлен в Библиотеке типов, а потому не отработается. (Не путать с представлением VT_LPWSTR для типа LPWSTR, который даст ожидаемое поведение).