Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / UDR и выравнивание в in-буфере / 24 сообщений из 24, страница 1 из 1
05.01.2016, 14:05
    #39142354
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Добрый день уважаемые...
Портирую тут код с UDF в UDR и обнаружил такую странность или недопонимание с моей стороны:
Если входные аргумены функции Integer - идет выравнивание на 4 байта, если в перемешку с Varchar - то нет.
т.е. в случае Delphi нужно в одном случае объявлять как
Код: pascal
1.
2.
3.
4.
5.
6.
  TFB_INT_INT = record
    Value_1: Integer;
    isNull_1: WordBool;
    Value_2: Integer;
    isNull_2: WordBool;
  end;

, а в другом как
Код: pascal
1.
2.
3.
4.
5.
6.
7.
  TFB_INT_VARCHAR_31 = packed record
    Value_1: Integer;
    isNull_1: WordBool;
    Len: Word;
    Text: array[0..30] of AnsiChar;
    isNull: WordBool;
  end;


с.м. пример:

Код: sql
1.
2.
3.
4.
5.
  CREATE FUNCTION UDR_FUNC_2(INT_ARG_1 INTEGER NOT NULL, INT_ARG_2 INTEGER NOT NULL) RETURNS VARCHAR(31)
  EXTERNAL name 'udr_test!func_2' engine udr;

  SELECT UDR_FUNC_2(1, 2)
  FROM RDB$DATABASE




Код: sql
1.
2.
3.
4.
5.
CREATE FUNCTION UDR_FUNC_1(INT_ARG_1 INTEGER NOT NULL, VARCHAR_ARG_2 VARCHAR(31) NOT NULL) RETURNS INTEGER
  EXTERNAL name 'udr_test!func_1' engine udr;

  SELECT UDR_FUNC_1(1, 'TEST_STR')
  FROM RDB$DATABASE




Firebird3 WI-V3.0.0.32246 x86

p.s. Симонов Денис, можете прокомментировать?
...
Рейтинг: 0 / 0
05.01.2016, 14:36
    #39142364
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs,

причём тут выравнивание? Для INTEGER идёт NULL значение и NULL признак. Для CHAR значение и NULL признак. Для VARCHAR текущая длина, значение и NULL признак.

Я себе небольшую заметку сделал что и куда маппится

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
/// ///////////////////////////////
///
/// BOOLEAN
/// Value: ByteBool
/// NullFlag: WordBool
///
/// SMALLINT
/// Value: SmallInt
/// NullFlag: WordBool
///
/// INTEGER
/// Value: Integer
/// NullFlag: WordBool
///
/// BIGINT
/// Value: LargeInt
/// NullFlag: WordBool
///
/// FLOAT
/// Value: Single
/// NullFlag: WordBool
///
/// DOUBLE PRECISION
/// Value: Double
/// NullFlag: WordBool
///
/// CHAR(N)
/// Value: array[0 .. N-1] of AnsiChar
/// NullFlag: WordBool
///
/// VARCHAR(N)
/// Length: Word
/// Value: array[0 .. N-1] of AnsiChar
/// NullFlag: WordBool
///
/// DATE
/// Value: ISC_DATE
/// NullFlag: WordBool
///
/// TIME
/// Value: ISC_TIME
/// NullFlag: WordBool
///
/// DATETIME
/// Value: ISC_TIMESTAMP
/// NullFlag: WordBool
///
/// BLOB
/// Value: ISC_QUAD
/// NullFlag: WordBool



Кстати есть и второй вариант не составлять эти структуры, а дёргать значения из буфера по смещению. Но он более сложный.
...
Рейтинг: 0 / 0
05.01.2016, 14:37
    #39142366
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Симонов ДенисViktor_bs,

причём тут выравнивание? Для INTEGER идёт NULL значение и NULL признак. Для CHAR значение и NULL признак. Для VARCHAR текущая длина, значение и NULL признак.



поправил
...
Рейтинг: 0 / 0
05.01.2016, 14:39
    #39142367
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs,

ещё надо учитывать что N в определениях array[0 .. N-1] of AnsiChar это байты. Поэтому если у вас параметр в UTF8 объявлен, то декларируемую длину надо на 4 умножить
...
Рейтинг: 0 / 0
05.01.2016, 14:42
    #39142369
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Ну и какое смещение будет для 2-го аргумента типа Integer и для 2-го аргумента типа Varchar, если первый аргумент функции Integer?
Картинки смотрели?

Симонов ДенисViktor_bs,

причём тут выравнивание? Для INTEGER идёт NULL значение и NULL признак. Для CHAR значение и NULL признак. Для VARCHAR текущая длина, значение и NULL признак.

Я себе небольшую заметку сделал что и куда маппится


Кстати есть и второй вариант не составлять эти структуры, а дёргать значения из буфера по смещению. Но он более сложный.
...
Рейтинг: 0 / 0
05.01.2016, 14:59
    #39142373
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs,

какая разница? Смещения интересны только в том случае если ты работаешь с буфером напрямую. Если ты создал record который описывает сообщение, то всё равно какое там смещение.

И ещё какого ты сделал packed record во втором примере?
...
Рейтинг: 0 / 0
05.01.2016, 15:14
    #39142376
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bsНу и какое смещение будет для 2-го аргумента типа Integersizeof(Integer)
Viktor_bsдля 2-го аргумента типа Varcharsizeof(Word)
Для CHAR было бы sizeof(Char)
Viktor_bsесли первый аргумент функции Integer?это вообще ни на что не влияет

Выравнивание зависит только от типа поля, и не зависит от того, что было перед ним.

PS не вникал, что конкретно в этом плане требуют UDR и требуют ли они чего-то особенного.
...
Рейтинг: 0 / 0
05.01.2016, 15:22
    #39142382
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Симонов ДенисViktor_bs,

какая разница? Смещения интересны только в том случае если ты работаешь с буфером напрямую. Если ты создал record который описывает сообщение, то всё равно какое там смещение.

И ещё какого ты сделал packed record во втором примере?
Да посмотрите вы наконец картинки, я же специально разрисовал :) В первом случае (для 2-х Integer) размер одного аргумента 8 байт, а во втором - 6 байт, потому и packed, а вчера с пересчетом указателей мозг себе взорвал :(
...
Рейтинг: 0 / 0
05.01.2016, 15:23
    #39142384
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bsвчера с пересчетом указателей мозг себе взорвал
Ну и забей.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.01.2016, 15:23
    #39142385
fb user
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs
Код: pascal
1.
2.
3.
4.
5.
6.
  TFB_INT_INT = record
    Value_1: Integer;
    isNull_1: WordBool;
    Value_2: Integer;
    isNull_2: WordBool;
  end;


Напишите как это будет выглядеть с packed record. И сразу вопрос прояснится.
...
Рейтинг: 0 / 0
05.01.2016, 15:26
    #39142387
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry SibiryakovViktor_bsвчера с пересчетом указателей мозг себе взорвал
Ну и забей.

Всмысле? :)
Это ошибка или я дурак?
На сегодняшний день я портировал 2 детка функций и по 5-ти из них угадываю с объявлениями буфера.
...
Рейтинг: 0 / 0
05.01.2016, 15:30
    #39142391
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs,

может тебе примерчик для работы с varchar кинуть?
...
Рейтинг: 0 / 0
05.01.2016, 15:30
    #39142392
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bsЭто ошибка или я дурак?
Второе.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.01.2016, 15:35
    #39142394
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry Sibiryakov,

да ладно тебе. Пусть учится.

По мне так в Delphi примеры даже понятней выглядят. На C++ Адриано всю грязную работу засунул в BOOSTовские макросы, что с первого взгляда хоть и выглядит просто, но ломает мозг при попытке осмысления что же происходит.
...
Рейтинг: 0 / 0
05.01.2016, 15:41
    #39142397
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Симонов Денисда ладно тебе. Пусть учится.
Бесполезно. В Дельфи нет опции для "оптимального" выравнивания структур, которое
используется в Си и, соответственно, буферах.

Симонов ДенисПо мне так в Delphi примеры даже понятней выглядят.

Но выравнивание приходится эмулировать дополнительными прокладками.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.01.2016, 15:50
    #39142402
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Симонов ДенисViktor_bs,

может тебе примерчик для работы с varchar кинуть?
Ага, давай для случая:
1. function(INTEGER, VARCHAR(31)) RUTERNS INTEGER
2. function(INTEGER, INTEGER) RUTERNS VARCHAR(31)
Заодно и сам поймешь о чем я, хотя Dimitry Sibiryakov уже указал направление.
...
Рейтинг: 0 / 0
05.01.2016, 16:26
    #39142427
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry SibiryakovСимонов Денисда ладно тебе. Пусть учится.
Бесполезно. В Дельфи нет опции для "оптимального" выравнивания структур, которое
используется в Си и, соответственно, буферах.

Симонов ДенисПо мне так в Delphi примеры даже понятней выглядят.

Но выравнивание приходится эмулировать дополнительными прокладками.


Спасибо. Нашел статью на Хабре по поводу выравнивания в сях - буду курить. Еще бы быть уверенным в том что от версии к версии (либо директив компилятора) оно все не съедет.

P.S. А вообще зачетную бомбу заложили дельфистам :)
...
Рейтинг: 0 / 0
05.01.2016, 16:29
    #39142428
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry SibiryakovВ Дельфи нет опции для "оптимального" выравнивания структур,
которое используется в Си и, соответственно, буферах.
Хотя нет, вот тут я вру. Умолчательное выравнивание (по крайней мере в моём Turbo Delphi)
вполне соответствует Сишному. Но всё равно надо за этим следить в оба глаза.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.01.2016, 16:31
    #39142430
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry SibiryakovБесполезно. В Дельфи нет опции для "оптимального" выравнивания структур, которое
используется в Си и, соответственно, буферах.

D6, XE3Record Types When a record type is declared in the {$A+} state (the default), and when the declaration does not include a packed modifier, the type is an unpacked record type, and the fields of the record are aligned for efficient access by the CPU, and according to the platform. The alignment is controlled by the type of each field. Every data type has an inherent alignment, which is automatically computed by the compiler. The alignment can be 1, 2, 4, or 8, and represents the byte boundary on which a value of the type must be stored in order to provide the most efficient access. The table below lists the alignments for all data types.
Но
D6, XE3In the {$A8} or {$A+} state, fields in record types that are declared without the packed modifier and fields in class structures are aligned on quad-word boundariesПочему-то я первой цитате (как и здравому смыслу) верю больше.

PS Не проверял.
...
Рейтинг: 0 / 0
05.01.2016, 16:34
    #39142434
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
hvladПочему-то я первой цитате (как и здравому смыслу) верю больше.

PS Не проверял.
Я проверил, первая цитата действительно правильная.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.01.2016, 17:32
    #39142459
Viktor_bs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Dimitry SibiryakovhvladПочему-то я первой цитате (как и здравому смыслу) верю больше.

PS Не проверял.
Я проверил, первая цитата действительно правильная.


Всем спасибо. Вопрос закрыт.
...
Рейтинг: 0 / 0
05.01.2016, 17:36
    #39142461
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
Viktor_bs,

мда мне оказывается везло. Ладно учту на будущее
...
Рейтинг: 0 / 0
05.01.2016, 18:40
    #39142471
Зимаргл
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
hvladDimitry SibiryakovБесполезно. В Дельфи нет опции для "оптимального" выравнивания структур, которое
используется в Си и, соответственно, буферах.

D6, XE3Record Types When a record type is declared in the {$A+} state (the default), and when the declaration does not include a packed modifier, the type is an unpacked record type, and the fields of the record are aligned for efficient access by the CPU, and according to the platform. The alignment is controlled by the type of each field. Every data type has an inherent alignment, which is automatically computed by the compiler. The alignment can be 1, 2, 4, or 8, and represents the byte boundary on which a value of the type must be stored in order to provide the most efficient access. The table below lists the alignments for all data types.
Но
D6, XE3In the {$A8} or {$A+} state, fields in record types that are declared without the packed modifier and fields in class structures are aligned on quad-word boundariesПочему-то я первой цитате (как и здравому смыслу) верю больше.

PS Не проверял.
Вероятно, второе утверждение для 64-бит компиляции. В любом случае надо проверять структуры ABI для 32- и 64- отдельно.

/* troll
И зачем в учебном языке какое то выравнивание структур =)
*/
...
Рейтинг: 0 / 0
05.01.2016, 19:31
    #39142492
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UDR и выравнивание в in-буфере
ЗимарглВероятно, второе утверждение для 64-бит компиляции.В D6 таковой не имеется
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / UDR и выравнивание в in-буфере / 24 сообщений из 24, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]