-
Доброй ночи! Подскажите пожалуйста... Я объявил перечисление и множество:
type EMyEnum = ( MyEnumA, MyEnumB, MyEnumC ); TMyEnum = EMyEnum; TMySet = Set Of TMyEnum; И написал функцию:
procedure MyTest(F: DWORD; E: TMyEnum; M: DWORD; S: TMySet; L: DWORD); begin // SizeOf(E) == 1 // SizeOf(S) == 1 ... end; Переменные-параметры получаются размером один байт. А сколько будет "выделено места" при их передаче? Тоже один? Или четыре? Этим можно как-то управлять? Я хочу чтоб все параметры были одинакового размера, чтоб в другой программе можно было импортировать и использовать мою функцию как: MyTest(DWORD, DWORD, DWORD, DWORD, DWORD). В данном случае мне даже не важно сколько будет SizeOf самой переменной, меня пока интересует конкретно выравнивание при передаче параметров. Хотя и про размер переменных тоже было бы хорошо разобраться, на будущее. Спасибо!
-
use Ord
-
-
Ord это в смысле функция возвращающая Integer или Int64? А зачем она мне тут? Я хочу чтоб унифицированный заголовок моей функции был "пять параметров по 4 байта каждый", для совместимости, но при этом в Делфи использовать некоторые параметры как перечисление или множество, для удобства и исключения ошибок.
>> but a set always resides in memory if it is larger than the platform-dependent integer type
Мне не нужно "больше чем integer type", мне нужно "точно равно 4 байта" или же "точно равно размеру integer type".
Кажется нашёл такое:
type {$MINENUMSIZE 4} EMyEnum = ( MyEnumA, MyEnumB, MyEnumC ); TMyEnum = EMyEnum; TMySet = Set Of TMyEnum; {$MINENUMSIZE 1} Но поправилось только первое, а второе всё равно один байт:
procedure MyTest(F: DWORD; E: TMyEnum; M: DWORD; S: TMySet; L: DWORD); begin // SizeOf(E) == 4 // SizeOf(S) == 1 ... end;
-
Надо чтоб параметры M и L были строго по смещению 8 и 16. Может просто добавить какой-нибудь stdcall? Чтоб функцию можно было импортировать как void MyTest(DWORD F, DWORD E, DWORD M, DWORD S, DWORD L); Научите пожалуйста, как смотреть/понимать в отладчике код вызова этой функции - сколько передаётся параметров, как передаётся, и какого они размера?
-
-
-
Описание чего? Там просто "что такое Set", я и так знаю что это. Но я же не это спрашиваю - а как заставить его быть размером в 4 байта. Этого там нету.
Что за Юникс-Гномы я не понял совсем...
По последней ссылке написано:
>> Sets, records, and static arrays of 1, 2, or 4 bytes are passed as 8-bit, 16-bit, and 32bit values.
Вывод - передаётся не так как я хочу. Ну а как принудительно заставить всегда быть 32bit? Там не сказано. Никак?
-
сет это 256 возможных членов. то есть физически это максимум 256 бит или 32 байта.
а как заставить его быть размером в 4 байта
чтобы стало 4 байта, надо сделать твой енум нужной длины (32 члена) и включить максимальный член в множество.
либо при проектировании выбирать типы данных не от балды, а со смыслом.
-
Если нужна связь с программами на других языках - я бы не рисковал Просто объявил ручками константы нужные (в каждой один бит в 1) и сам тип объявил нужным мне
Ибо гадать с размерами и проч., а потом вылавливать не понятные кривости поведения - удовольствие так себе.
-
> Там не сказано. Никак?
Зачем это вам? Всё равно в других языках нет аналога set of. Так что работать с ним не сможете. Делать конвертер, так лучше сразу со стороны вашей библиотеки. Тем более это внешняя связь, а значит данные требуют проверки и нормировки пред их применением.
-
если нужны DWORD значит и переменные должны быть DWORD, в масиве/еще как то не принципиально (если в общем а не под задачу).
> Чтоб функцию можно было импортировать как void MyTest(DWORD F, DWORD E, DWORD M, DWORD S, DWORD L); и кстати параметры в функцию передаются через стек, а не массивом/сетом за раз... если понял смысл поста.
-
Я хочу использовать в своём коде удобные мне вещи - перечисление и множество. Читать удобнее, писать удобнее (Code Completion адаптируются), дорабатывать удобнее, RTTI подхватывает тип, отлаживать удобнее. Плюс они добавляют дополнительную защиту от неправильного использования. А когда какую-то часть функций понадобится экспортировать - то эти "другие языки которые не уметь set of" - пусть себе тогда они объявляют заголовок как DWORD и передают константы (раз уж они не могут иначе). Чего это я должен отказываться от очень хороших плюшек, из-за того что другие чего-то там не умеют?
> чтобы стало 4 байта, надо сделать твой енум нужной длины (32 члена) и включить максимальный член в множество.
гм! Добавил пунктов MyEnum* до 32 штук - стало 4 байта! Спасибо! Вот только что делать если мне их там стока не нужно? Допустим что нужно три... Мешаются же остальные. Можно ли их как-то оставить в объявлении, но исключить из использования? Имею ввиду запретить использовать в коде и не показывать в Code Completion? Deprecated получается применять только ко всему перечислению...
type {$MINENUMSIZE 4} EMyEnum = ( MyEnumA, // 1 MyEnumB, // 2 MyEnumC, // 3 MyEnumReserved4, MyEnumReserved5, MyEnumReserved6, MyEnumReserved7, MyEnumReserved8, MyEnumReserved9, MyEnumReserved10, MyEnumReserved11, MyEnumReserved12, MyEnumReserved13, MyEnumReserved14, MyEnumReserved15, MyEnumReserved16, MyEnumReserved17, MyEnumReserved18, MyEnumReserved19, MyEnumReserved20, MyEnumReserved21, MyEnumReserved22, MyEnumReserved23, MyEnumReserved24, MyEnumReserved25, MyEnumReserved26, MyEnumReserved27, MyEnumReserved28, MyEnumReserved29, MyEnumReserved30, MyEnumReserved31, MyEnumReserved32 ); {$MINENUMSIZE 1}
-
> Допустим что нужно три... 4 байта это всего один DWORD, три байта никак нельзя, если конечно хочешь "делить память" DWORD-ами. так то у set-а увеличение побайтное, вроде... (не проверял, может еще как то выравнивание влияет), т.е. убери последние минимум 8 максимум 15 значений и будет тебе 3 байта.
-
> Чародей Ученика (09.07.18 14:29) [12] > А когда какую-то часть функций понадобится экспортировать > - то эти "другие языки которые не уметь set of" - пусть > себе тогда они объявляют заголовок как DWORD и передают > константы (раз уж они не могут иначе).
Другие просто скажут "а иди ты лесом с таким интерфейсом" И будут правы.
"Если ты плюнешь в коллектив - коллектив утрётся. Если коллектив плюнет в тебя - утонешь."
-
> три байта никак нельзя
Это было не про "байты", а про количество элементов в описании EMyEnum. А размер нужен эквивалентный DWORD. Но он уже получен. Просто неудобно что 29ть лишних холостых MyEnum* болтаются.
> Другие просто скажут "а иди ты лесом с таким интерфейсом"
А какое дело "другим" до внутреннего устройства моей системы? И почему я должен из-за кого-то урезать свой внутренний инструментарий? И я же как раз универсальности и добиваюсь: умеете работать с "set of" - используйте вот такой-то "set of", не умеете - используйте DWORD и такие-то константы. Всё по желанию/возможностям.
-
> Просто неудобно что 29ть лишних холостых MyEnum* болтаются. set of byte - максимальный размер.
TMyEnumWord = 0..31; TMySet = set of TMyEnumWord; - "удобный" размер;
-
> не умеете - используйте DWORD и такие-то константы. с константами геморрой будет, типа в сете 1, а в дворде 4096 и т.д. ... ну или типа, смотря как там в памяти хранится, а оно вовсе не биты в линеечку слева направо как тебе похоже представляется.
-
> смотря как там в памяти хранится хотя, с первой половиной (до 16) проблем не будет, после значение скачет, т.к. старший ворд располагается по младшему адресу... проверь var
s: set of 0..31;
d: dword absolute s;
begin
s:= [16]; Edit1.Text:= IntToStr(d);
end;
-
-
Я хочу использовать в своём коде удобные мне вещи - перечисление и множество.
как уже выяснилось выше эти удобные на первый взгляд вещи очень неудобны в конкретном приложении, которое хочет фиксированный размер. зачем оно этого таки хочет - уже другой вопрос, ответ на который тоже лежит в плоскости реально правильного выбора типов. а не с потолка.
-
вот чем таким там удобен енум длиной три(!) элемента?
тем что у них будет гламурный if x in myset вместо if x and mydword = x ??
фигня это а не удобство.
|