if not CreateProcess(PChar(Converter), PChar('"' + Converter + '" "' + SrcFile + '" "' + Result + '" /storefile'), nil, nil, False, 0, nil, nil, SI, PI) then
Нет, программа при этом запустится, но вот параметры к ней будут испорчены. Почему? Посмотрим на типы переменных:
Converter
- это AnsiString
, т.к. это глобальная переменная внутри DLL. SrcFile
- это тоже AnsiString
, т.к. это временная переменная внутри процедуры. А вот Result
- это WideString
, т.к. он передаётся между DLL и главным приложением.Что будет, когда мы соединяем строки нескольких разных типов? Чтобы избежать потери информации, компилятор вынужден сконвертировать Ansi-строки в Unicode-строки. Это значит, что всё выражение
'"' + Converter + '" "' + SrcFile + '" "' + Result + '" /storefile'
в целом имеет тип WideString
. Приводя такую строку к PChar
, получим строку, состоящую всего из одного символа '"'
. Разумеется, ParamStr
в вызываемой программе в этом случае покажет полную ерунду.Вообще говоря, компилятор в таких случаях генерирует предупреждения о "подозрительном приведении типов". Но стабильность генератора предупреждений в Delphi иногда оставляет желать лучшего. Иногда хинты/предупреждения могут не показываться, а иногда показываться в ненужных местах. Конкретно в этом месте никакого предупреждения компилятор показать не счёл нужным. Получили загадочную ситуацию на пустом месте: вроде бы программа вызывается с нужными параметрами (мы под отладчиком видим, что параметры в
CreateProcess
передаются верно), но в самой программе параметров нет.Как это можно исправить? Например, поставить явное приведение к нужному типу:
if not CreateProcess(PChar(String(Converter)), PChar(String('"' + Converter + '" "' + SrcFile + '" "' + Result + '" /storefile')), nil, nil, False, 0, nil, nil, SI, PI) thenа можно собрать сперва строки в переменную типа
AnsiString
.Кстати, заметим, что в Delphi 2009 приведённый код работает на ура. Предлагаю самостоятельно подумать почему.
Потому что в D2009 вызывается CreateProcessW?
ОтветитьУдалитьПотому что в D2009 String - это WideString
ОтветитьУдалить