Страница 1 из 1

Выравнивание на границу

Добавлено: 13 Апрель 2018, 10:32
Constantine
Нужно выровнять переменную на границу DWORD. В С так:
// Align cbAcl to a DWORD.
cbAcl = (cbAcl + (sizeof(DWORD) - 1)) & 0xfffffffc;
Пишу:
cbACL#=BAND(cbACL#+3,0fffffffcH)

Это правильно или нет? А как правильно?
Спасибо!

Выравнивание на границу

Добавлено: 13 Апрель 2018, 11:28
Дед Пахом
Слова вроде все знакомые, а смысла уловить не получается. День сегодня такой, наверно.

Выравнивание на границу

Добавлено: 13 Апрель 2018, 11:37
Constantine
Мне нужно, чтобы значение переменной cbACL# было выровнено на границу двойного слова (DWORD). Есть пример выравнивания на С. Правильно ли я перевел на Clarion?

Выравнивание на границу

Добавлено: 13 Апрель 2018, 13:59
kreator
Обычно вот так:

Код: Выделить всё

DWORD                   EQUATE(ULONG)
Попробуйте объявите свою переменную таким способом и ничего выравнивать не придётся. В WinAPI так работает. Но там паскалевское соглашение. Для сишного соглашения нужно в прототипе внешней функции поставить C вместо PASCAL. И то это имеет значение (судя по хелпу) только для возвращаемых из внешней функции значений (что-то там со стэком по-разному).

Выравнивание на границу

Добавлено: 13 Апрель 2018, 14:27
Constantine
Правильно ли я понял, что ULONG автоматически выравнивается на границу DWORD?

Выравнивание на границу

Добавлено: 13 Апрель 2018, 14:41
Constantine
Отвечаю сам себе: да, с С перевел правильно. Это, действительно, работает так... Переменная выравнивается на границу DWORD.

Выравнивание на границу

Добавлено: 13 Апрель 2018, 22:50
RaFaeL
Я тоже мало что понял, но если речь о передаче структур в в процедуры С, то проще всего выравнивать руками, передаешь адрес группы, а в группе переменными BYTE (или большими, если надо выравнять на несколько байт сразу) двигаешь ту, что передаешь, куда надо https://forum.clarionlife.net:443/viewt ... f=5&t=4072

Выравнивание на границу

Добавлено: 16 Апрель 2018, 9:03
Constantine
Вспоминаем школу... :-)
Выравнивание на границу двойного слова означает, что АДРЕС первого байта данных переменной должен быть кратен четырем.
Соответственно, выравнивание на границу слова означает, что АДРЕС первого байта данных переменной должен быть кратен двум.
Меня смутили способ, которым это предлагает делать MSDN и правильность моего перевода этого безобразия на Clarion.
Однако, как ни странно, и то и другое оказалось правильным, в чем я и убедился...
Добавление байтов в группу изменит ее ДЛИНУ, а никак не АДРЕС первого байта, так что этот способ не пойдет...

Выравнивание на границу

Добавлено: 16 Апрель 2018, 10:15
PavelNK
Constantine писал(а): 16 Апрель 2018, 9:03Добавление байтов в группу изменит ее ДЛИНУ, а никак не АДРЕС первого байта, так что этот способ не пойдет...
этот способ меняет адрес следующей переменной, если объявит массив байт, то в нем можно нарезать сколько угодно много переменных с любым выравниванием

Выравнивание на границу

Добавлено: 16 Апрель 2018, 12:41
Constantine
Ну, тогда сначала нужно выровнять этот массив байт...

Выравнивание на границу

Добавлено: 16 Апрель 2018, 16:27
PavelNK
Constantine писал(а): 16 Апрель 2018, 12:41Ну, тогда сначала нужно выровнять этот массив байт...
Зачем? Можно определить номер элемента массива, соответствующий требованию, и присвоить его адрес переменной с которой в дальнейшем работать

Выравнивание на границу

Добавлено: 16 Апрель 2018, 16:50
Constantine
Можно.
Для этого нужно:
1. Получить адрес массива.
2. Проверить, кратен ли он четырем.
3. Прибавить разницу до ближайшего кратного.
4. Получить требуемое.

Напоминаю, в начале речь шла о переменной LONG, а не о массиве или группе...
В итоге, все 4 действия сделаны одной строкой...