powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Не получить корректный Record по указателю из С++ DLL
47 сообщений из 47, показаны все 2 страниц
Не получить корректный Record по указателю из С++ DLL
    #40035572
Фотография Kast2K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, коллеги!

Дельфи 10.3.3

Есть железяка и DLL от производителя.
Описание вызова:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
#include "fwlib32.h" or "fwlib64.h"

FWLIBAPI short WINAPI cnc_diagnoss(unsigned short FlibHndl, short number, short axis, short length, ODBDGN *diag);

length   [ in ]

Specify the data block length(size of ODBDGN structure).

    4+(byte size of diagnosis data) * (number of axis) 

typedef struct  odbdgn {
   short datano;              /* diagnosis data number */
   short type;                /* upper byte:type */
                              /* lower byte:axis */
   union {
      char  cdata;            /* bit/byte diagnosis data */
      short idata;            /* word diagnosis data */
      long  ldata;            /* 2-word diagnosis data */
      char  cdatas[MAX_AXIS]; /* bit/byte diagnosis data with axis*/
      short idatas[MAX_AXIS]; /* word diagnosis data with axis */
      long  ldatas[MAX_AXIS]; /* 2-word diagnosis data with axis */
   } u ;
} ODBDGN ;



Основываясь на C# примере (с диска производителя)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
		void Button2Click(object sender, EventArgs e)
		{
			short a = Convert.ToInt16(textBox10.Text); //308		
			
		//	ConnectionID=32769;
			ODBDGN oo = new ODBDGN();
			string ss="";
			short b = 8; // (-1);

			status = cnc_diagnoss(ConnectionID,a,b,12,oo); //4+1*8
 			foreach (byte qq in oo.cdatas)
			{
				 ss = ss+ qq.ToString();
			}
			textBox1.Text = textBox1.Text + String.Format("Data : {0}\n\r\n\rValues : {1}\n\r\n\r",oo.datano,ss);
		}



получаю результат как на экране железяки, например, 75 68 65 68 0 0 0 0

пытаюсь получить тоже самое в Delphi

Код: 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.
51.
52.
53.
54.
55.
56.
57.
58.
59.
const
  MAX_AXIS=8;

  Podbdgn = ^Todbdgn;
  Todbdgn=packed record
    datano:SmallInt;
    dtype:SmallInt;

    LDATAS: array[0..MAX_AXIS-1] of byte;
  end;

function cnc_diagnoss (FlibHndl:Word; number: SmallInt; axis: SmallInt; length :SmallInt; diag:Podbdgn):SmallInt;stdcall;external 'Fwlib32.dll';

procedure TForm2.Button1Click(Sender: TObject);
var
  i:Integer;
  h:Word;
  odData:Podbdgn;
  odD:Todbdgn;
  ip:AnsiString;
  s:string;
begin
  h:=0;
  try
    try

      ip:='10.*.*.*';
      i:=cnc_allclibhndl3(PAnsiChar(ip),45001,5, @h);
      Memo1.Lines.Add('i='+i.ToString);

      if (i=0) then
        begin
          Memo1.Lines.Add('cd found');
          New(odData);
          ShowMessage(sizeof(odD).ToString);

          i:=cnc_diagnoss(h, smallint(seNum.Value), SmallInt(MAX_AXIS), {SmallInt(4+(4*(MAX_AXIS-1)))}sizeof(odD), odData);
          Memo1.Lines.Add('cd i='+i.ToString);

          Memo1.Lines.Add(odData^.datano.ToString +'|'+odData^.dtype.ToString{+'|'+odData^.ldata.ToString});
          for I := 0 to MAX_AXIS-1 do
            begin
                s:=odData^.LDATAS[i].ToString;
                Memo1.Lines.Add(i.ToString+':='+s);
            end;
          Dispose(odData);
        end;
    except on E: Exception do
      Memo1.Lines.Add('ERROR='+e.Message);
    end;

  finally
    if h<>0 then
      begin
        cnc_freelibhndl(@h);
        Memo1.Lines.Add('Fanuc closed success');
      end;
  end;
end;



В результате вижу следующее:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
i=0
cd found
cd i=0
308|8
0:=81
1:=0
2:=0
3:=0
4:=84
5:=111
6:=112
7:=116
Fanuc closed success



Предположил, что проблема в длине принимаемого массива внутри union. Изменил:
Код: pascal
1.
LDATAS: array[0..MAX_AXIS-1] of byte; -->>LDATAS: array[0..MAX_AXIS-1] of LongInt;



Результат:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
i=0
cd found
cd i=0
308|8
0:=72
1:=10
2:=6553699
3:=6684704
4:=7667823
5:=6553710
6:=655373
7:=0
Fanuc closed success



Записал лог Wireshark
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
0000   48 2a e3 83 a9 72 2c 4f 52 ea 6a 1b 08 00 45 00
0010   00 6c e5 93 00 00 3c 06 30 2a 0a 75 12 1d 0a 75
0020   41 c8 af c9 ec 1f 31 a1 11 37 5a e3 59 10 50 18
0030   21 b4 ad 19 00 00 a0 a0 a0 a0 00 02 21 02 00 3a
0040   00 01 00 38 00 01 00 01 00 30 00 00 00 00 00 00
0050   00 28 00 00 01 34 00 08 00 00 00 00 00 48 30 30  //308 и 8 получаемые вижу, всё последующее нет.
0060   30 38 20 38 00 00 00 00 00 00 00 00 00 00 00 00
0070   00 00 00 00 00 00 00 00 00 00



Подскажите, пожалуйста, что я упускаю при работе с данной Си++ функцией? Может надо как-то по иному вызывать её? Или дельфи некорректно обрабатывает её ответ?

Спасибо!

ЗЫ. Код писал только для теста получения данных
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035593
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот это
Kast2K
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
typedef struct  odbdgn {
   short datano;              /* diagnosis data number */
   short type;                /* upper byte:type */
                              /* lower byte:axis */
   union {
      char  cdata;            /* bit/byte diagnosis data */
      short idata;            /* word diagnosis data */
      long  ldata;            /* 2-word diagnosis data */
      char  cdatas[MAX_AXIS]; /* bit/byte diagnosis data with axis*/
      short idatas[MAX_AXIS]; /* word diagnosis data with axis */
      long  ldatas[MAX_AXIS]; /* 2-word diagnosis data with axis */
   } u ;
} ODBDGN 

записывается так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
odbdgn = record
  datano: SmallInt;
  type_: SmallInt;
  case Byte of
    0: (cdata: ShortInt);
    1: (idata: SmallInt);
    2: (ldata: Integer);
    3: (cdatas: array[0..MAX_AXIS - 1] of ShortInt);
    4: (idatas: array[0..MAX_AXIS - 1] of SmallInt);
    5: (ldatas: array[0..MAX_AXIS - 1] of Integer);
end;

Функцию можно объявить так
Код: pascal
1.
function cnc_diagnoss (FlibHndl:Word; number: SmallInt; axis: SmallInt; length: SmallInt; var diag: odbdgn):SmallInt; stdcall; external 'Fwlib32.dll';


Kast2K
Код: pascal
1.
//308 и 8 получаемые вижу, всё последующее нет.

Тут вам нужно смотреть документацию на функцию и что и когда она возвращает
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035646
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

odbdgn = record надо объявлять как odbdgn = packed record, иначе делфовский компилятор выравняет поля в завиисмости от {$ALIGN XX}
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035651
Фотография Kast2K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги,
спасибо за подсказки!

Но, как оказалось, я сам лопух :) не дочитал спецификацию на дополнительные вычисляемые параметры оборудования и передавал не тот параметр.

Всё работает отлично.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035675
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
dbdgn = record надо объявлять как odbdgn = packed record,
Не надо. И даже вредно.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035677
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
asutp2
dbdgn = record надо объявлять как odbdgn = packed record,
Не надо. И даже вредно.

Обоснуй?
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035704
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Обоснуй?

С++ вроде по-умолчанию использует выравнивание то ли 4 то ли 8 байт, как и Delphi.
Это в WinApi всё packed.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035732
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Это в WinApi всё packed.
Ничего подобного. В WinApi структуры упакованы сами по себе. Там все поля либо четырехбайтовые, либо появляются всякие reserved.

Пример
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;

typedef struct _SECURITY_DESCRIPTOR {
  BYTE                        Revision;
  BYTE                        Sbz1;
  SECURITY_DESCRIPTOR_CONTROL Control;
  PSID                        Owner;
  PSID                        Group;
  PACL                        Sacl;
  PACL                        Dacl;
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;

Смотри на первые три поля. В сумме 4 байта и все само пакуется
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035777
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-BrutalОбоснуй?

Ты не поверишь, но Си тоже выравнивает поля. Причём чаще всего точно так же как Дельфи.

Но иногда некоторые указывают Дельфи неверное выравнивание. Поэтому при портировании и непонятках со структурами, первое, что надо сделать, это вывести общую длину структуры и смещение каждого поля в Си и Дельфи. Потом сравнить.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035786
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
alekcvp
Это в WinApi всё packed.
Ничего подобного. В WinApi структуры упакованы сами по себе. Там все поля либо четырехбайтовые, либо появляются всякие reserved
Не всегда) Пример - работа с RAS.
Для работы со структурой rassconn требуется {$ALIGN 4}, для всех остальных структур {$ALIGN 8}, a reserved в структурах практически нет вообще
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035807
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
Для работы со структурой rassconn требуется {$ALIGN 4},
Она и так сама выровняется на 4 байта, если ей не помешать
asutp2
для всех остальных структур {$ALIGN 8},
Ссылку в студию
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035816
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035839
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
asutp2
Для работы со структурой rassconn требуется {$ALIGN 4},
Она и так сама выровняется на 4 байта, если ей не помешать
что значит "сама"? вообще то выравнивание как раз регулируется директивой ALIGN. Лично у меня в проектах для виндов по умолчанию именно $ALIGN 8, а не 4, для macos - $ALIGN 16
_Vasilisk_
asutp2
для всех остальных структур {$ALIGN 8},
Ссылку в студию
что, всё плохо с доступом к описанию API в MSDN?
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035843
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Лично у меня в проектах для виндов по умолчанию именно $ALIGN 8, а не 4, для macos - $ALIGN 16

Именно это я и имел ввиду когда говорил про чудаков, ставящих левые настройки куда не надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035859
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

asutp2Лично у меня в проектах для виндов по умолчанию именно $ALIGN 8, а не 4, для macos - $ALIGN 16

Именно это я и имел ввиду когда говорил про чудаков, ставящих левые настройки куда не надо.
Учитывая, что используемые мною значения как раз и рекомендуются Эмбаркадерой (внимательно смотрим ссылку ), то чудик тут тот, кто не следует обоснованным рекомендациям
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035860
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот только нет по ссылке такой рекомендации.

"For OS X applications, stack alignment must be on 16-byte boundaries."

Внезапно, но "stack alignment" не имеет никакого отношения к "field alignment" и второе не
влияет на первое.

Впрочем, что взять с вики...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035871
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

речь идет именно о field alignment, слово stack это всего лишь описка. Поищи в web-архиве эту статью из блога, там было всё подробно расписано
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035872
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://web.archive.org/web/20090523104516/https://blogs.embarcadero.com/eboling/2009/05/20/5607
In the Mac OS X ABI Function Call Guide there is an innocent little sentence: "The stack
is 16-byte aligned at the point of function calls."

Перевести или сам как-нибудь справишься?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035876
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
речь идет именно о field alignment, слово stack это всего лишь описка.

Дефолтное выравнивание полей записи: dccosx - 8, dccosx64 - 16.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035894
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

так сейчас актуально только dccosx64, а 32и битные уже всё, в истории
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035895
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

http://web.archive.org/web/20090523104516/https://blogs.embarcadero.com/eboling/2009/05/20/5607
In the Mac OS X ABI Function Call Guide there is an innocent little sentence: "The stack
is 16-byte aligned at the point of function calls."

Перевести или сам как-нибудь справишься?..
Давай жги)
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035899
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Давай жги)

"Значение указателя стэк при вызове функции должно быть кратно 16 байт."

Я не знаю какой кретин сумел это хоть как-то связать с выравниванием полей записи, но
надеюсь, что он всё ещё работает в Эмбаркадеро и не может навредить остальному миру.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035900
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну вот, собственно, о чем я и говорил. Интерфейсные форматы оставлять на откуп платформе и компилятору - плохой путь, ничем не лучше DateToStr(Now).
Вот описали кучу сишных структур без всякой привязки, рассчитывая на выравнивание по 4, а потом в конечном софте вдруг кто-то вхрненачил прагму на 8, а тупорылая сишная манера "сначала засунем все инклюды в один огромный исходник, а его будем компилировать" запросто позволит этой прагме повлиять на ВСЁ, что идет и подключается за ней.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035936
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Смотри на первые три поля. В сумме 4 байта и все само пакуется

А ты вообще понимаешь что такое выравнивание?
Если ты эту структуру в Delphi опишешь, то у тебя будет так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
type
_SECURITY_DESCRIPTOR = record
    Revision: Byte;
    { Padding: array [0..6] of Byte; }
    Sbz1: Byte
    { Padding: array [0..6] of Byte; }
    ....
  end;

То что закомментировано добавит компилятор.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035943
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЕсли ты эту структуру в Delphi опишешь, то у тебя будет так:

Нет, так будет только у asutp2 и ему подобных, которые употребляют опции выравнивания где
не надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035947
Barmaley57
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
_Vasilisk_
Смотри на первые три поля. В сумме 4 байта и все само пакуется

А ты вообще понимаешь что такое выравнивание?
Если ты эту структуру в Delphi опишешь, то у тебя будет так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
type
_SECURITY_DESCRIPTOR = record
    Revision: Byte;
    { Padding: array [0..6] of Byte; }
    Sbz1: Byte
    { Padding: array [0..6] of Byte; }
    ....
  end;

То что закомментировано добавит компилятор.
Ну не. Скорее уж так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
type
_SECURITY_DESCRIPTOR = record
    Revision: Byte;
    Sbz1: Byte
    { Padding: array [0..1] of Byte; }
    i:integer;
    ....
  end;
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035948
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

alekcvpЕсли ты эту структуру в Delphi опишешь, то у тебя будет так:

Нет, так будет только у asutp2 и ему подобных, которые употребляют опции выравнивания где
не надо.

Да, реально, я почему-то думал что он каждое поле будет выравнивать.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40035999
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

alekcvpЕсли ты эту структуру в Delphi опишешь, то у тебя будет так:

Нет, так будет только у asutp2 и ему подобных, которые употребляют опции выравнивания где
не надо.
Не, ты что реально что ли настолько тупой?
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036000
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я реально портировал более чем достаточно структур с Си на Дельфи чтобы знать о чём говорю.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036003
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И поэтому ты видимо считаешь, что только один в теме, а все остальные - тупни?

Я выше уже приводил пример работы с API (а именно с RAS), где для работы со структурой rasconn требуется именно {$ALIGN 4}, а для всех остальных структуру требуется {$ALIGN 8}.
Хотя о чем это я, гуру ведь говорит иначе!)
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036074
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
И поэтому ты видимо считаешь, что только один в теме, а все остальные - тупни?

Я выше уже приводил пример работы с API (а именно с RAS), где для работы со структурой rasconn требуется именно {$ALIGN 4}, а для всех остальных структуру требуется {$ALIGN 8}.
Хотя о чем это я, гуру ведь говорит иначе!)
А для каких остальных нужно 8? В ras.h действительно стоит #pragma pack(4) вначале файла, и больше я там не нашел переключений выравнивания.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036079
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Ничего подобного. В WinApi структуры упакованы сами по себе. Там все поля либо четырехбайтовые, либо появляются всякие reserved.
Не, на самом деле в заголовках windows sdk довольно много #pragma pack раскидано, часто парами типа #pragma pack(push,1) / #pragma pack(pop). Плюс еще есть pshpack1.h - pshpack16.h которые много где инклудятся.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036083
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Хотя о чем это я, /гуру/ ведь говорит иначе!)

А теперь подыми глаза повыше и перечитай что именно говорит гуру.

Повторяю медленно: при любых непонятках со структурами надо первым делом сравнивать
размеры и смещения каждого их поля. И общий размер структуры тоже если она используется в
массиве.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036101
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone
asutp2
И поэтому ты видимо считаешь, что только один в теме, а все остальные - тупни?

Я выше уже приводил пример работы с API (а именно с RAS), где для работы со структурой rasconn требуется именно {$ALIGN 4}, а для всех остальных структуру требуется {$ALIGN 8}.
Хотя о чем это я, гуру ведь говорит иначе!)
А для каких остальных нужно 8? В ras.h действительно стоит #pragma pack(4) вначале файла, и больше я там не нашел переключений выравнивания.
Я использовал например RasConnStatus, RasEapInfo, RasDialParams, RasEntryName, RasEntry, RasDialExtensions, RasStats - они и для x32 и для x64 корректно работают при {$ALIGN 8}

Dimitry Sibiryakov

asutp2Хотя о чем это я, /гуру/ ведь говорит иначе!)

А теперь подыми глаза повыше и перечитай что именно говорит гуру.

Повторяю медленно: при любых непонятках со структурами надо первым делом сравнивать
размеры и смещения каждого их поля. И общий размер структуры тоже если она используется в
массиве.
ок, смотрим выше твое же сообщение
Dimitry Sibiryakov

alekcvpЕсли ты эту структуру в Delphi опишешь, то у тебя будет так:

Нет, так будет только у asutp2 и ему подобных, которые употребляют опции выравнивания где
не надо.
Так ты уже определись наконец, что делать ПОСЛЕ того, как определены расхождения?
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036114
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Так ты уже определись наконец, что делать ПОСЛЕ того, как определены расхождения?

ПОСЛЕ - аккуратно применять опции выравнивания если они нужны.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036116
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
Я использовал например RasConnStatus, RasEapInfo, RasDialParams, RasEntryName, RasEntry, RasDialExtensions, RasStats - они и для x32 и для x64 корректно работают при {$ALIGN 8}
"корректно работают при {$ALIGN 8}" и "требуется {$ALIGN 8}" это немножко разное. Вполне может быть, что работают. А RASCONN на WIN64 и правда сломается.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036117
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Повторяю медленно: при любых непонятках со структурами надо первым делом сравнивать
размеры и смещения каждого их поля. И общий размер структуры тоже если она используется в
массиве.
Можно конечно и так, но обычно проще в исходник посмотреть. Правда, иногда (но не в случае winapi) надо еще и знать, с какими параметрами проект на С собирается.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036119
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бывают конечно казусы. Например, в какой-то старой версии delphi TGUID был описан как packed record. Вот тогда в одном месте пришлось действительно проверять смещение каждого поля. Кода исправили, не знаю, но сейчас в 10.2 packed для TGUID уже нет. И выравнивается он теперь как положено - на 4.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036124
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barloneобычно проще в исходник посмотреть.

....а там в объявлении макросы на typedef-ы и пока дойдёшь до настоящего типа, состаришься.
Проще тестовую программку на экран размером сляпать.

А уж если кто-то применил тип long, так вообще начинается самая забава...
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036127
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone
asutp2
Я использовал например RasConnStatus, RasEapInfo, RasDialParams, RasEntryName, RasEntry, RasDialExtensions, RasStats - они и для x32 и для x64 корректно работают при {$ALIGN 8}
"корректно работают при {$ALIGN 8}" и "требуется {$ALIGN 8}" это немножко разное. Вполне может быть, что работают. А RASCONN на WIN64 и правда сломается.
Эмба рекомендует использовать {$ALIGN 8}, поэтому такое выравнивание и используется. SizeOf(структура) и требуемый размер совпадают, вызовы функций работают корректно. Для rasconn используется {$ALIGN 4}, ситуация аналогична.

Dimitry Sibiryakov

asutp2Так ты уже определись наконец, что делать ПОСЛЕ того, как определены расхождения?

ПОСЛЕ - аккуратно применять опции выравнивания если они нужны.
в данной конкретной ситуации нужны и поэтому используются. Продолжить мысль?
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036130
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Лично у меня в проектах для виндов по умолчанию именно $ALIGN 8, а не 4, для macos - $ALIGN 16

asutp2в данной конкретной ситуации нужны и поэтому используются.

Продолжайте мысль.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036195
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
Эмба рекомендует использовать {$ALIGN 8}, поэтому такое выравнивание и используется.
Вот тут неправильно. Она конечно рекомендует, но это относится к случаям, когда вы не взаимодействуете с чужим кодом или сами устанавливаете правила этого взаимодействия. А когда у вас есть готовый чужой код, который вы не можете менять, ALIGN должен соответствовать тому, что есть в этом коде. Для структур, передающихся в этот код, естественно. Для остальных можно следовать рекомендациям.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036212
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone
asutp2
Эмба рекомендует использовать {$ALIGN 8}, поэтому такое выравнивание и используется.
Вот тут неправильно. Она конечно рекомендует, но это относится к случаям, когда вы не взаимодействуете с чужим кодом или сами устанавливаете правила этого взаимодействия. А когда у вас есть готовый чужой код, который вы не можете менять, ALIGN должен соответствовать тому, что есть в этом коде. Для структур, передающихся в этот код, естественно. Для остальных можно следовать рекомендациям.
Всё правильно, согласен. В моем конкретном случае структуры в RAS работают именно с ALIGN8 (кроме одной), поэтому во всем коде, включая описание этих самых структур, рекомендуемый алижн и используется.

Dimitry Sibiryakov

asutp2Лично у меня в проектах для виндов по умолчанию именно $ALIGN 8, а не 4, для macos - $ALIGN 16

asutp2в данной конкретной ситуации нужны и поэтому используются.

Продолжайте мысль.
Я вообще не улавливаю смысла претензии. Поясните.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036224
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone
Например, в какой-то старой версии delphi TGUID был описан как packed record. Вот тогда в одном месте пришлось действительно проверять смещение каждого поля. Кода исправили, не знаю, но сейчас в 10.2 packed для TGUID уже нет. И выравнивается он теперь как положено - на 4.

Кровавые подробности? Так-то полям TGUID выравнивание не требуется. (у поля D3 смещение - 6, например).
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036231
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Barlone
Например, в какой-то старой версии delphi TGUID был описан как packed record. Вот тогда в одном месте пришлось действительно проверять смещение каждого поля. Кода исправили, не знаю, но сейчас в 10.2 packed для TGUID уже нет. И выравнивается он теперь как положено - на 4.

Кровавые подробности? Так-то полям TGUID выравнивание не требуется. (у поля D3 смещение - 6, например).

На С есть
Код: plaintext
1.
2.
3.
4.
struct {
short a;
GUID b;
...

И тут у нас 2 байта паддинга между a и b.
Транслируем на паскаль, и b прилепляется к a, несмотря на {$ALIGN 4}, потому что у packed record собственное выравнивание 1.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036233
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone,

Но packed оно о внутренней компоновке полей записи, а не о самой записи в составе другого типа.
...
Рейтинг: 0 / 0
Не получить корректный Record по указателю из С++ DLL
    #40036238
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Но packed оно о внутренней компоновке полей записи, а не о самой записи в составе другого типа.

Проверил. И правда влияет...
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Не получить корректный Record по указателю из С++ DLL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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