Как проверить, является ли объект NULL в Inno Setup Pascal Script?

Я пишу паскальскую функцию, используя Inno setup studio, которая проверяет, является ли объект нулевым и что-то делает.

пока у меня есть:

XMLDocument.setProperty('SelectionLanguage', 'XPath');
XMLNode := XMLDocument.selectSingleNode(APath);
if (XMLNode=Null) then
begin
//do stuff
End
Else
//do other stuff
End

но я продолжаю получать invalid variant operation ошибку.

Как мне проверить, является ли объект нулевым в коде сценария Inno Setup Pascal Script?


person user1    schedule 04.11.2014    source источник
comment
Неназначенный объект относится к nil. NULL - функция, возвращающая вариант NULL. Итак, вы хотели написать if (XMLNode = nil) then или if not Assigned(XMLNode) then, который делает то же самое.   -  person TLama    schedule 04.11.2014
comment
@TLama Я получаю Type Mistmatch при попытке скомпилировать код, если я изменяю его на то, что вы предлагаете?   -  person user1    schedule 04.11.2014
comment
Что ж, давайте начнем с того, что расскажем нам, какой компилятор вы используете. FreePascal, Delphi или что-то еще? Измените теги вопросов.   -  person TLama    schedule 04.11.2014
comment
@TLama Я использую Inno Setup Compiler. Сейчас я отредактирую свой вопрос, чтобы сделать его более полезным   -  person user1    schedule 04.11.2014


Ответы (1)


Чтобы проверить, является ли Variant NULL, используйте функцию VarIsNull:

if VarIsNull(XMLNode) then

Однако в вашем случае проблема немного сложнее. Метод selectSingleNode всегда возвращает вариант введите varDispatch, фактический указатель данных которого указывает на найденный узел XML DOM, или на nil, если такой узел не найден. В Delphi (язык, на котором написан сценарий Inno Setup Pascal) есть VarIsClear , которая охватывает и такую ​​ситуацию. К сожалению, он не опубликован в Inno Setup. Однако вы можете проверить этот случай с помощью такого утверждения:

if (IDispatch(XMLNode) = nil) then

Это получит данные из возвращенного варианта varDispatch и этих тестов данных для nil.


Мартин Лаан добавил функцию VarIsClear в Unicode-версию Inno Setup в this commit, поэтому с момента установки Inno 5.5.6 вы можете использовать VarIsClear вместо описанного выше хака.

person TLama    schedule 04.11.2014
comment
Думаю, вы предвидели мою проблему. Согласно документации DOM XML selectSingleNode возвращает null. Но по какой-то причине моя программа на самом деле просто не присваивает значение, если узел xpath не существует, поэтому мне действительно нужен VarIsEmpty, но это правильный ответ на вопрос, который я задал. Спасибо! - person user1; 04.11.2014
comment
Пожалуйста! Что ж, проблема немного глубже. Значение, возвращаемое вызовом selectSingleNode (при использовании позднего связывания), всегда имеет тип varDispatch (даже если узел не найден). Тестирование с VarIsNull или VarIsEmpty в любом случае не удастся. Вам необходимо получить доступ к данным значения этого varDispatch варианта и проверить, nil. Смотрите обновление. - person TLama; 04.11.2014
comment
Спасибо за обновления. В моем случае, если я перехожу на IDispatch, я получаю Type Mismatch, но если я использую VarIsEmpty, он действительно работает. то есть в моем приложении, если элемент не существует, я вставляю элемент, иначе я обновляю и отображаю разные окна сообщений. и varIsEmpty вроде работает. Спасибо за информацию, я посмотрю дальше - person user1; 04.11.2014
comment
Это странно. VarIsEmpty также не должен работать в ANSI Inno Setup в этом случае. Возвращаемый тип по-прежнему varDispatch (проверено в версии 5.5.4 (a)). VarIsEmpty функция должна проверять, только если вариант имеет тип varEmpty (а это не так, поэтому VarIsEmpty должен возвращать False, но это не так). Что касается несоответствия типов, есть проблема с as преобразованием, если вы напишете if (IDispatch(XMLNode) = nil) then, то оно будет работать, как ожидалось (и это правильный путь). - person TLama; 04.11.2014
comment
Да if (IDispatch(XMLNode) = nil) then работает. Если вы посоветуете это сделать, я буду придерживаться его. Странно, что VarIsEmpty работает? Возможно ошибка в программе? - person user1; 04.11.2014
comment
Если его значение должно быть таким же, как в Delphi (и я уверен, что должно), то это ошибка, потому что as _ 1_ (а также реализация, которая только проверяет, является ли тип варианта varEmpty) говорит: VarIsEmpty не указывает, когда вариант, представляющий интерфейс, имел интерфейс указатель очищен, и это именно тот случай. VarType возвращает varDispatch, что означает, что возвращенный вариант не является пустым (он бы вернул varEmpty, если бы был). - person TLama; 04.11.2014
comment
В Unicode Inno Setup это работает должным образом. Здесь VarIsEmpty возвращает правильное значение. Но лучше всего сначала проверить тип варианта, например if VarType(XMLNode) = varDispatch then. Если такая проверка не удалась, то метод вернул что-то, что не является ссылкой на интерфейс узла DOM. В случае успеха вы можете безопасно проверить данные, выполнив приведение к IDispatch. - person TLama; 04.11.2014
comment
Итак, в ANSI Inno Setup вы можете безопасно использовать VarIsEmpty в этом случае. Он также проверяет, является ли тип varDispatch и данные там nil. Однако это не будет работать в Unicode Inno Setup. Вот краткое discussion о Это. - person TLama; 05.11.2014