Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Вниз

BOOL   Найти похожие ветки 

 
Тимохов ©   (2004-04-12 14:22) [0]

Уважаемые мастера!

Вопрос для знатоков использования win api в дельфи.

В vs c++ есть тип BOOL (большими). Который равен int (или unsigned int, точно не помню). В windows.pas есть тип BOOL = LongBool.

При этом ord(LongBool(true)) = -1, тогда как TRUE (большими), которое определено в vs c++ равно 1. Т.е. в c++ под истинным значением типа BOOL считается 1, тогда как в дельфи для типа BOOL истинным считается -1.

Мне абсолютно понятно, почему многие функции winapi (например createprocess),  импортированный в windows.pas, имеют результирующий тип BOOL и при этом работают правильно. Дело в том, что для типа LongBool дельфи сама преобразует любое отличное от 0 значения в истинное значение. Это мне понятно и вопросов не вызывает.

Но! Есть функции callback. Например первый параметр функции EnumCalendarInfo (используется в sysutils.pas ~9700 строка д6). Заметим, что не смотря на то, что результат callback описан в MSDN как возвращающий BOOL, в дельфи он описан как integer, и возвращаются явно 1 и 0, а не true и false. Мною проверено, что если callback описать как BOOL и возвращать true и false - работать не будет - true и false означают одно и то же.

Вопрос вообще говоря не праздный т.к. в windows.pas есть не все импорты функций win api - иногда приходится делать это самому.

Итак вопрос. Скажите какими принципами вы руководствуетесь когда импортируете функции win api в дельфи? Выше ясно показано, что чисто формально это сделать сложно. Есть ли методики, основанные не только на опыте?


 
Ega23 ©   (2004-04-12 14:27) [1]

Всё очень просто. ЛОЖЬ (False) - это НОЛЬ. ИСТИНА - это НЕ НОЛЬ.

Поэтому в C имеет право на сущ. такая запись:
SC_HANDLE hServ;
hSCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCMan) return (UPRStatusErrorSCManager);

А если в Delphi попробовать привести
i:=Integer(True), то скорее всего тебе 1 выдаст (хотя я не стал бы доверять на 100%)


 
Тимохов ©   (2004-04-12 14:29) [2]

Вы думаете, что просто?
Я тоже так думал.
По вашей логике (я считал также) тот кто ждет от меня результата callback так и должен думать - 0 ложь, не 0 истина. Но не фига. Под истиной считается именно 1.

Проверено для указанного в вопросе callback"a.


 
Игорь Шевченко ©   (2004-04-12 14:33) [3]

Тимохов ©   (12.04.04 14:22)  

Поздравляю! Натолкнулся на ту же проблему, что и я некоторое время назад.

Все NLS-Enumerators в Windows требуют Callback, описанный как
function (blah-blah): Integer; stdcall;

для продолжения перечисления необходимо вернуть единицу, для прекращение любой, отличное от единицы число, например 0.

Это относится конкретно к NLS-Enumerators (EnumSystemCodePages, EnumSystemLanguageGroups, EnumCalendarInfo, и т.д.)

Результаты анализа выявили, что внутри этих функций производится непосредственное сравнение возвращенного Callback"ом значения с единицей. Так вот в MS пишут :(


 
Ega23 ©   (2004-04-12 14:34) [4]

А как же тогда

The four predefined Boolean types are Boolean, ByteBool, WordBool, and LongBool. Boolean is the preferred type. The others exist to provide compatibility with different languages and the Windows environment.
A Boolean variable occupies one byte of memory, a ByteBool variable also occupies one byte, a WordBool variable occupies two bytes (one word), and a LongBool variable occupies four bytes (two words).

Boolean values are denoted by the predefined constants True and False. The following relationships hold.

Boolean ByteBool, WordBool, LongBool
False < True False <> True
Ord(False) = 0 Ord(False) = 0
Ord(True) = 1 Ord(True) <> 0
Succ(False) = True Succ(False) = True
Pred(True) = False Pred(False) = True
A value of type ByteBool, LongBool, or WordBool is considered True when its ordinality is nonzero. If such a value appears in a context where a Boolean is expected, the compiler automatically converts any value of nonzero ordinality to True.
The remarks above refer to the ordinality of Boolean values—not to the values themselves. In Object Pascal, Boolean expressions cannot be equated with integers or reals. Hence, if X is an integer variable, the statement

if X then ...;

generates a compilation error. Casting the variable to a Boolean type is unreliable, but each of the following alternatives will work.

if X <> 0 then ...;        { use longer expression that returns Boolean value }
var OK: Boolean            { use Boolean variable }

...
if X <> 0 then OK := True;
if OK then ...;


 
Тимохов ©   (2004-04-12 14:39) [5]


> Ega23 ©   (12.04.04 14:34) [4]

Дельфи может писать, что угодно, но в LongBool true по сути является -1, а не 1.


> Игорь Шевченко ©   (12.04.04 14:33) [3]


Именно nls. Вообще я на это набрел не потому как нужно, а потому как решил внимательно прочесть Рихтера, а у него начало про unicode - вот и решил разобраться с unicode и заодно с интернациональизацией.

Хотите ли вы сказать, что в других местах (не nls), где написано в MSDN, что функция возвращает BOOL, Вы без стаха напишете в дельфи BOOL или все-таки напишете integer?

Еще вопрос по сям: int яслвятеся generic типом, также как integer в дельфи?


 
Игорь Шевченко ©   (2004-04-12 14:43) [6]


> Хотите ли вы сказать, что в других местах (не nls), где
> написано в MSDN, что функция возвращает BOOL, Вы без стаха
> напишете в дельфи BOOL


Напишу.


>  int яслвятеся generic типом, также как integer в дельфи?


Да


 
Ega23 ©   (2004-04-12 14:45) [7]

Дельфи может писать, что угодно, но в LongBool true по сути является -1, а не 1.
Или $FFFFFFFF....
Мда, а я  всё время boolean писал.... То-то я смотрю, что наши программеры, что на С пишут, предпочитают числами пользоваться...


 
Тимохов ©   (2004-04-12 14:47) [8]


> Игорь Шевченко ©   (12.04.04 14:43) [6]

Нипишите, говорите. Я может тоже напишу. Но просто интересно, откуда берется такая смелость. Ведь явно же видно, что TRUE в си и true типа longbool вообще говоря разные вещь - первый 1, второй -1.
Т.е. не погу понять откуда в борланда такая самоувереность в подмене типа... :((


 
Anatoly Podgoretsky ©   (2004-04-12 14:52) [9]

LongBool true по сути не является -1 и не 1, а <> 0.
А то что какой то программист жестко закодировал его в своей функции как -1 или 1 в некоторых функция сути не меняет. Смотреть надо страндарты C++


 
Anatoly Podgoretsky ©   (2004-04-12 14:54) [10]

Выражение в Си if x истинно, если x <> 0


 
gek ©   (2004-04-12 14:56) [11]

Anatoly Podgoretsky ©   (12.04.04 14:52) [9]

Именно так, отличное от 0 ->истина, остальное ->ложь


 
Игорь Шевченко ©   (2004-04-12 14:59) [12]

Anatoly Podgoretsky ©   (12.04.04 14:54)

Именно так. Но в реализации пресловутых функций написано:

if (x == 1)
 true_part;
else
 false_part;

Это к тому, что криво могут писать не только наши программисты...


 
Тимохов ©   (2004-04-12 15:00) [13]


> Anatoly Podgoretsky ©   (12.04.04 14:52) [9]

То что true, это не 0, я знаю - сам раньше писал на с (лет 12 назад).

Вопрос в другом. Уверен, что каждый программист хочет писать надежные программы, основываясь на проверенной и четкой методике.

Одна из возможноым методик деланься чего-нибудь с использованием функций winapi:
1. Лезишь в msdn
2. видишь, что результат нужной тебе функции BOOL
3. идешь в windows.pas, конечно, думая, что это модуль есть точное отображение нужный h заголовков.
4. находишь в windows.pas BOOL. О круто - такой тип есть. Его и будем использовать.
5. доделфаешь проект, а ничего не работает (см. исходный вопрос).
6. в результате анализа в h файле находишь, что BOOL = int и TRUE = 1.
7. исправляешь - все работает.

В итоге получается, что верить windows.pas нельзя (в качестве BOOL оказался не то, что нужно). Оказываешься в тупике - совершенно не понятна методка общения с win api. Вот меня и интересует, кто какой методикой пользуется...


 
Ega23 ©   (2004-04-12 15:01) [14]

Именно так, отличное от 0 ->истина, остальное ->ложь

Я бы несколько по другому сказал: 0 - Ложь, остальное - Истина. :о)
Хотя сути это не меняет.


 
Ega23 ©   (2004-04-12 15:04) [15]

if (x == 1)
true_part;
else
false_part;

А где такое,  если не секрет?


 
Тимохов ©   (2004-04-12 15:05) [16]


> Игорь Шевченко ©   (12.04.04 14:59) [12]

вообще то говоря это явно сказано в msnd, что нужно именно TRUE, которое в одном из h описана как 1.
Одним словом - в данном случае все понятно.

Мне все же не понятна смелось борладна описывать результат createprocess как BOOL - в хелпе же ясно сказано

Return Value
If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

т.е. удачно, когда TRUE, т.е. строго 1!!!

Опять же скажу, что эта смелость мне понятна - дельфи автоматически преобразует для типа LongBool все не 0 в true.

Но имхо это как-то все кривовато, хотя и успешно работает...


 
Anatoly Podgoretsky ©   (2004-04-12 15:16) [17]

Тимохов ©   (12.04.04 15:00) [13]

Это плохо написаные программы, не соответсвующие стандарту языка, это равносильно если в Дельфи писать if x = true, вместо if x

Значение константы true несколько раз менялось, это было и 1 и минус 1, сравнение с константой идеологически неверно, признак низкой квалификации программиста, его согласие с тем, что его программа может отказать работать как задумано.
Это примерно такая же ошибка, как var + 2, вместо var + sizeof(type) многие Си программисты и не только они хлебнули горя при переходе int с 2 байт на 4 или при трансляции на другой платформе.

Так поступать нам не к лицу.


 
Тимохов ©   (2004-04-12 15:27) [18]

Делаю вывод: с win api все работают на основе опыта и здравого смысла, а не только на основе последнего.

ЕЩЕ ВОПРОС.

В winapi часто встречаются структуры (struct) для разных параметров. Например, TCPInfo для функции GetCPInfo. Легко заметить, что в дельфи это структруа описана как record, а не packed record. При этом легко заметить, что при определенных обстоятельствах (не для этой структуры, а для каких-нибудь других) здесь может съиграть роль вырванивание полей.

Вопрос: Почему у борланда есть уверенность, что выравнивание в си и в дельфи сделано одинаково?


 
Игорь Шевченко ©   (2004-04-12 15:41) [19]


> Вопрос: Почему у борланда есть уверенность, что выравнивание
> в си и в дельфи сделано одинаково?


Тебе не кажется, что этот вопрос разумнее Борланду задать ?

Ega23 ©   (12.04.04 15:04)
> А где такое,  если не секрет?


В NLS-Enumerators


 
Тимохов ©   (2004-04-12 15:43) [20]


> Игорь Шевченко ©   (12.04.04 15:41) [19]
> Тебе не кажется, что этот вопрос разумнее Борланду задать
> ?


Хорошая идея.
Для начала хотел у местных мастеров повыяснять.


 
Anatoly Podgoretsky ©   (2004-04-12 15:44) [21]

У них не может быть уверенности даже насчет одной и той же версии Дельфи, поскольку управляемый параметр. Их спасает только то, что модуль не перекомпилируется, но стоит только сделать то как все может рухнуть.


 
Тимохов ©   (2004-04-12 15:47) [22]


> Anatoly Podgoretsky ©   (12.04.04 15:44) [21]

Ну Вы меня порадовали :)))))

Тогда скажите как жить дальше если нужно импортировать структуру из win api, которой еще нет в windows.pas? Т.е. делать packed или делать какое-то определенное выравнивание?


 
Тимохов ©   (2004-04-12 15:54) [23]

Меня тут осенило - может в windows.pas отключено выравнивание и все record становятся packed? Посмотрел - нет, не так, второй строкой идет {$ALIGN ON}.

:(((((

Ну ничего не понимаю...


 
clickmaker ©   (2004-04-12 15:55) [24]

> Тимохов ©   (12.04.04 15:47) [22]

Если в сишной декларации стоит #pragma pack(1) перед структорой, то packed


 
Ega23 ©   (2004-04-12 15:55) [25]

Тимохов ©   (12.04.04 15:47) [22]
ДЛЛ на С++ не спасёт?


 
Тимохов ©   (2004-04-12 15:58) [26]


> Ega23 ©   (12.04.04 15:55) [25]

Да у меня то проблем нет.
Просто интересно - разбирась.


 
Anatoly Podgoretsky ©   (2004-04-12 15:59) [27]

Тимохов ©   (12.04.04 15:47) [22]
Самому писать и так что бы размещение соответствовало истине.

Тимохов ©   (12.04.04 15:54) [23]
А ты уверен, что Борландом компилировался именно этот текст :-)

Ega23 ©   (12.04.04 15:55) [25]
Не спасет, со структурой то он будет работать в Дельфи.


 
Игорь Шевченко ©   (2004-04-12 16:00) [28]

Тимохов ©   (12.04.04 15:58)

Если у тебя возникают такие трудности, то могу дать хороший совет - не используй то, в чем так сильно сомневаешься.


 
Anatoly Podgoretsky ©   (2004-04-12 16:00) [29]

Это обсуждение очень хорошо коррелируются в предыдущими по надежности кода, включая недавнее.


 
Тимохов ©   (2004-04-12 16:19) [30]


> Anatoly Podgoretsky ©   (12.04.04 16:00) [29]

Анатолий.
Я так понимаю, что вы не хотите делится секретами :)))))
Именно на это меня наводит фраза: "Самому писать и так что бы размещение соответствовало истине". В общем-то вас можно понять :))))))


> Игорь Шевченко ©   (12.04.04 16:00) [28]

Именно так я всегда и делаю. А если вдруг окажется надо? Ведь должна же быть методика гарантированного результата. Т.е. почитал, сделал, причем сделал корректно.


 
Ega23 ©   (2004-04-12 17:24) [31]

Не спасет, со структурой то он будет работать в Дельфи.

Не факт, что с со ВСЕЙ структурой. Может из клиента всего 1-2 параметра передать (или получить) надо



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.033 c
11-1066225387
.::D.e.M.o.N.i.X::.
2003-10-15 17:43
2004.05.02
MpegAudio Tools


4-1078388144
Serega_____
2004-03-04 11:15
2004.05.02
Введение новой оконной процедуры


14-1081685140
Undert
2004-04-11 16:05
2004.05.02
Windows XP logon


14-1081426665
Nikolay M.
2004-04-08 16:17
2004.05.02
На какого героя советских мультиков вы больше всего похожи?


14-1081678222
Ломброзо
2004-04-11 14:10
2004.05.02
Диалоги запросов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский