Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > IXMLDocument убивается раньше времени


Автор: kami 18.10.2012, 16:46
Доброго времени суток, господа!
Вновь я с вопросом по непонятной мне области...
Имеем: D2010, Win7.
Код, работающий в дополнительном потоке (на всякий случай - синхронизация с другими потоками не требуется, очередь сообщений создана):

Код

function TAddressModule.GetNodeListFromXML(XMLStream: TStream): IXMLNodeList;
var
  xml: IXMLDocument;
  root: IXMLNode;
  resultNode: IXMLNode;
begin
  // CoInitializeEx(nil, COINIT_MULTITHREADED) вызывается в конструкторе.
  Result := nil;

  xml := TXMLDocument.Create(nil); // тут всё нормально, IXMLDocument создается
  xml.LoadFromStream(XMLStream, xetUTF_8);
  xml.Active := True;
  root := xml.Node.ChildNodes.FindNode('root');
  if Assigned(root) then
    begin
      resultNode := root.ChildNodes.FindNode('result');
      if Assigned(resultNode) then
        Result := resultNode.ChildNodes;
    end;
  // весь код отрабатывает "на ура", Result - валидный указатель.

end; // а вот тут вызывается xml.Release, сам xml высвобождается и всё рушится. Выявлено трассировкой FastMM

Соответственно, по выходу из функции Result указывает в никуда...
Как победить и возможно ли это? Не хотелось бы выносить этот код выше по уровню вложенности - ему много где предстоит использоваться...

P.S. С xml работать пришлось впервые, так что если есть ошибки/некорректности помимо основного вопроса - также буду признателен на указание оных.

Автор: lomaster 18.10.2012, 17:01
Ну а чего вы хотели от интерфейсной ссылки? больше ее никто не использует ее разрушили.
Клонировать надо в результат ваш лист.
Либо менять подход, к примеру переложить в список объектов, либо XMLDocument создавать раньше а сюда передать параметром, либо еще как, ... от задачи надо исходить.

Автор: bems 18.10.2012, 17:54
Цитата(lomaster @  18.10.2012,  17:01 Найти цитируемый пост)
Ну а чего вы хотели от интерфейсной ссылки? больше ее никто не использует ее разрушили.

не знаю что хочет ТС, а я хотел бы чтобы объект, реализующий IXMLNodeList хранил ссылку на докумет. Хотя с другой стороны наверное привело бы к циклической ссылке

Автор: kami 18.10.2012, 19:53
Цитата(lomaster @  18.10.2012,  17:01 Найти цитируемый пост)
больше ее никто не использует ее разрушили.

Как это - никто не использует? Мне очень нужна ее "дочка" - IXMLNodeList.
И мне крайне непонятно, почему при наличии ссылки на нужный мне интерфейс убивается его родитель, убивая тем самым и нужную мне информацию.
Цитата(bems @  18.10.2012,  17:54 Найти цитируемый пост)
а я хотел бы чтобы объект, реализующий IXMLNodeList хранил ссылку на докумет.

Имхо, было бы неплохо.

Победить это, я так понял, нереально? Значит, придется пересматривать эту часть кода... Эх, где наша не пропадала...

Автор: MetalFan 18.10.2012, 21:18
На то они и интерфейсы. Мало-ли какая там дочка кому нужна. Ссылок на сам интерфейс ноль - интерфейс уничтожился.
И это очень удобно и логично на мой взгляд. А если учитывать, что кто-то где-то на дцатого чилда ссылается, так представляю, как весь этот механизм тормозить начнет.

Автор: lomaster 18.10.2012, 21:51
Цитата

Как это - никто не использует?
 У вас в коде это написано.
Цитата

Мне очень нужна ее "дочка" - IXMLNodeList.
 Мало ли кто чего хочет, вы лучше объясните как должен счетчик на IXMLDocument узнать и инкрементится, через астрал?
Руками делайте, только вот как вы потом декремент делать будете я даже и предположить не могу. smile

Добавлено через 9 минут и 15 секунд
Цитата

так что если есть ошибки/некорректности помимо основного вопроса 
 Ну не то чтобы ошибки, а просто на будущее, "поднимите" xpath.

Автор: Чучмек 18.10.2012, 22:25
Код

xml._AddRef;

Автор: kami 18.10.2012, 22:35
Ну ладно, ладно, пристыдили  smile 
Код будет переделан с учетом этой особенности.

Добавлено через 4 минуты и 52 секунды
Вот только одного в толк не возьму - до того, как перенес этот код в рабочее приложение, тестировал его в однопоточном VCL (простейший вывод результата в мемо). И никаких проблем не было...


Чучмек, этого, если честно, хотелось избежать. Ибо в приведенной здесь реализации некому будет делать xml.Release... Или я неправильно понял?

Автор: Чучмек 18.10.2012, 23:02
Цитата(kami @  18.10.2012,  22:35 Найти цитируемый пост)
Ибо в приведенной здесь реализации некому будет делать xml.Release

Да некому. Я сейчас попробовал получить через IXMLNodeList "родителя" - IXMLDocument. Но увы :(

Автор: Чучмек 18.10.2012, 23:33
У IXMLNodeList "родителя" не нашел, а вот у IXMLNode есть OwnerDocument - вот это он и есть родимый.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)