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


Автор: Ptica_Oz 28.6.2010, 15:27
Всем здрасти.
Поставила тут на днях Delphi 2010 триальную версию (30 дней). Пробую старый код (Delphi 7) перевести. Почитала про всякие сложности, про Unicode... А застопорилась на бональном If!  smile  Вот кусочек:
Код

function Function(stParam: ansistring; ...): boolean;
begin
  ...
  Result := false;

  if stParam = 'Hello' then begin
  
    ShowMessage(stParam);
    Result := True
    Exit;
  end
  ...


Так вот условие выполняется, но в тело не заходит. Проходила пошагово - не заходит. Просто ставила значение True, тогда работает. Оптимизацию кода отключала и в свойствах проект, и {$O-} писала, не помагло.

Подскажите, пожалуйста, что не так?

Автор: AntonN 28.6.2010, 18:06
Код

'Hello'

в юникоде?

Автор: DarkProg 28.6.2010, 19:57
Цитата(Ptica_Oz @  28.6.2010,  15:27 Найти цитируемый пост)
Проходила пошагово - не заходит

Какую кнопку жмакали????

Автор: ~FoX~ 28.6.2010, 20:36
Ptica_Oz, в 2k9 работает... При условии что реально передается 'Hello'
Ну только название функции поменять надобно, 
function Function(stParam: ansistring; ...): boolean;
да ";" поставить...
Result := True

Показывай всю функцию... и вызовы

Автор: Ptica_Oz 29.6.2010, 08:23
Цитата(AntonN @  28.6.2010,  18:06 Найти цитируемый пост)
в юникоде?

эм, затрудняюсь ответить... но в Watch List вырожение stParam = 'Hello' определяется как true


Цитата(DarkProg @  28.6.2010,  19:57 Найти цитируемый пост)
Какую кнопку жмакали???? 

и F7 и F8

Цитата(~FoX~ @  28.6.2010,  20:36 Найти цитируемый пост)
Показывай всю функцию... и вызовы

Да нет больше в функции ничего, она только и делает, что слово проверяет, пока... а находится она в dll...

Автор: Ptica_Oz 30.6.2010, 16:21
загвоздка именно в операции сравнения строк... 
пробовала так:
Код

var
  st : AnsiString;
  i : integer;
begin
  st := 'menu_GetAttrList';
  i := AnsiCompareStr(stFunction, st);
  if i = 0 then begin

    ShowMessage('menu_GetAttrList');
    Result := true; 
    Exit;
  end


i  всегда получает значение -1
как можно сравнить строки типа AnsiString?

Автор: Ptica_Oz 1.7.2010, 08:24
сделала так:
Код

var
  st : AnsiString;
begin
  Result := false;
  st := 'Hello!';
  if (Pos(stFunction, st) = 1) and (Length(stFunction) = Length(st))then begin
    Result := true;
    Exit;
  end


Заработало, но как-то это громоздко. Может кто что умного посоветует...

Автор: RomanEEP 1.7.2010, 12:09
Удивительно! Только сейчас разобрался в чем дело.
Дело в том, что, как известно в строках в дельфи помимо её символов и завершающего нуля в начале хранятся 2 интеджера: счетчик ссылок на данный экземпляр строки и количество символов в ней. Однако с приходом юникода ситуация немного изменилась и добавился еще один интеджер - кодировка строки. Из-за этого нововведения делфи присравнении срок сперва преобразует их в юникод на основании кодировки строки, и только потом сравнивает.  Поэтому внешне одинаковые строки могут оказаться разными из-за несовместимости кодировки.

От этого можно уйти таким образом:
Код

if RawByteString(st) = RawByteString(stFunction) then
  ...

тогда сравнение пройдет по старинке, потому что RawByteString - специальны тип Ansi строки с кодировкой $FFFF, что означает игнорировать кодировку.

Автор: Ptica_Oz 1.7.2010, 15:17
неа, не работает...
в Watch List также пишет, что RawByteString(st) = RawByteString(stFunction) есть true, но всё равно идёт выполнение веточки else  smile 
может среду (компилятор) как-нибудь настроить надо?

Автор: RomanEEP 2.7.2010, 16:14
Странно... Можешь посмотреть какой реальный код компилируется для такого сравнения (нажать во время отладки этой строчки Ctrl + Alt + C) 
и посмотреть какая конкретно вызывается процедура сравнения (содержит Cmp или Compare и имеет префикс типа _Ansi, _Utf8)
Если немного знаешь асм, то можешь зайти внутрь этой процедуры XXXCmp и посмотреть после какого  je/jne он выпрыгивает из процедуры сравнения (приходит на команду ret).
ЗЫ: И еще посмотри, не подставляет ли компилятор перед функцией сравнения функции конвертации строк.

Автор: Демо 3.7.2010, 19:17
Ptica_Oz, 

Приведи не только функцию, но и её вызов.

Автор: Keeper89 3.7.2010, 21:18
Демо, +1, вдруг передается юникодная строка.

И есть ли ворнинги компилятора в этих кусках кода?

Автор: bems 3.7.2010, 21:30
вот это вот
Код

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

 function Foo(stParam: ansistring): boolean;
 begin
 Result := false;
 writeln(stParam = 'Hello');
 end;

begin
  try
    Foo('Hello');
    readln
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

выводит True
Или пусть ТС покажет как она получает параметр, или пусть проверит апдейты среды (у меня 4/5)

Автор: CodeMonkey 3.7.2010, 21:47
Ptica_Oz, кидайте сюда весь проект, мы посмотрим. А то так гадать долго можно.

Автор: Ptica_Oz 5.7.2010, 08:14
Во вложении проект... В общем, это пример плагина для одной системы документооборота. Он был разработан на Delphi7. Сейчас пытаюсь перевести его на Delphi 2010. Изменение кодировок - это первая задача с которой я столкнулась, там ещё много чего менять надо будет...
Комментарии по коду: в MainUnit есть функция PgiCheckMenuItem, она определяет активность пункта меню в зависимости от условий, вот в ней-то и происходит сравнение строк.

Автор: RomanEEP 5.7.2010, 08:36
Скомпилил dll заменив
if (Pos(stFunction, st) = 1) and (Length(stFunction) = Length(st)) then
на
 if st = stFunction then
Создал тестовый проект:
Код

program RunTest;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  PIClasses;

function PgiCheckMenuItem(stFunction: ansistring; RunMethod: TRunMethod;
  ParentVersion, ChildVersion: TVersion;
  stLinkName, DataBaseName, stCheckOut: ansistring): boolean; stdcall;
    external 'PgiExample.pgi';

begin
    PgiCheckMenuItem('menu_GetAttrList', nil, nil, nil, '', '', '')
end.

Усё работает идеально, условие проходит, что надо выполняет!

ЗЫ: Все компилил под D2010
ЗЗЫ: Для сравнения компилятор подставляет LStrEqual

Автор: Ptica_Oz 5.7.2010, 08:59
Во вложении скриншот пошаговой отладки.

Цитата(bems @  3.7.2010,  21:30 Найти цитируемый пост)
апдейты среды (у меня 4/5)

у меня тоже

может настройки компилятора изменить?...

Автор: bems 5.7.2010, 14:41
Как это вы передаете AnsiString в dll без ShareMem?
А вызывающий код в чем склмпилирован? Не в доюникодной версии ли?

Автор: CodeMonkey 5.7.2010, 15:00
PgiCheckMenuItem - это не Лоцман-ли? Он же в ANSI версии Delphi собран. Забудьте про Unicode и Delphi 2009/2010 - там такой кривой интерфейс с плагинами, что по-другому никак.

Добавлено через 2 минуты и 37 секунд
P.S. Во-первых, внутреннее устройство AnsiString в D2009/2010 <> устройства AnsiString в D2007 и ниже. Во-вторых, там исключения передаются через границы модулей - т.е. ваш код в D2009/2010 ловит исключение-объект из D2007 или ниже - это не будет работать, ибо структура объектов у этих Delphi разная.

Добавлено через 3 минуты и 28 секунд
P.P.S. Вот, что получается, когда экономят деньги на нормальных программистах и сажают студентов писать софт.

Автор: Ptica_Oz 5.7.2010, 16:17
Цитата(bems @  5.7.2010,  14:41 Найти цитируемый пост)
А вызывающий код в чем склмпилирован? Не в доюникодной версии ли?

угу, кажется в Delphi 7

Цитата(CodeMonkey @  5.7.2010,  15:00 Найти цитируемый пост)
PgiCheckMenuItem - это не Лоцман-ли?

он самый... через COM интерфейс на Delphi с ним не доводилось работать?

Автор: CodeMonkey 5.7.2010, 16:25
Цитата(Ptica_Oz @  5.7.2010,  17:17 Найти цитируемый пост)
через COM интерфейс на Delphi с ним не доводилось работать? 

А в чём вопрос-то?

Добавлено через 8 минут и 10 секунд
P.S. А это случайно я не с вами пересекался на DelphiKingdom по вопросу Компаса и печати на виртуальном принтере? smile

Автор: Ptica_Oz 16.7.2010, 15:09
сделала так:

Код

function Function(AFunction: PAnsiChar; ...): Boolean;
var
    LFuncName: String;
begin
        ...
        LFuncName := String(AFunction);
        if LFuncName = 'ProjectList' then
             ...

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