Как присвоить байт [] к записи

Слишком поздно, но может помочь. Я сделал для базы 10, если вы меняете базу, вам нужно позаботиться о том, как вычислить цифру 0 в *p-'0'.

Я бы использовал правило Хорнера для вычисления значения.

#include 
void main(void)
{
  char *a = "5363", *p = a;
  int unsigned base = 10;
  long unsigned x = 0;
  while(*p) {
    x*=base;
    x+=(*p-'0');
    p++;
  }
  printf("%lu\n", x);
}

5
задан Rob Kennedy 19 May 2009 в 14:50
поделиться

3 ответа

Вы также можете использовать ключевое слово absolute, чтобы заставить обе структуры использовать один и тот же адрес памяти:

var
  Data: array[1..SizeOf(TMyStruct)] of byte;
  s : TMyStruct absolute Data;

Любые данные, записанные в S, также доступны как Data без необходимости выполнять перемещение или преобразование указателя .

4
ответ дан 14 December 2019 в 01:16
поделиться

Это может быть сложно, поскольку вам нужно убедиться, что макеты исходной и целевой структуры идентичны. Если да, то у вас есть 2 варианта: либо использовать указатель на массив данных, либо использовать копию памяти:

Указатель:

type
  // Declare a pointer type for your struct.
  PMyStruct = TMyStruct^;

...

var
  ptr: PMyStruct;
begin
  ptr := PMyStruct(Cardinal(@Data));
  // use ptr...
end;

Копия памяти:

var
  Data: array of Byte;
  s: TMyStruct;
begin
  // fill Data...
  if SizeOf(s) <> Length(Data) then
    raise Exception.Create('Input size is not the same size as destination structure.');
  CopyMemory(@s, @Data, Length(Data));
  // use s...
end;
2
ответ дан 14 December 2019 в 01:16
поделиться

Вы можете делать в Delphi именно то, что вы делали бы в C ++. Тем не менее, определите именованный тип для указателя записи, поскольку Delphi не позволяет вам определять типы в операторах.

type
  PPacket = ^TPacket;
var
  packet: PPacket;

packet := PPacket(@data[0]);
  • Я использовал @data [0] , потому что он работает независимо от того, данные - это динамический массив. Если это динамический массив, то data на самом деле является указателем на первый байт пакета, так что это будет работать:

     packet: = PPacket (data); // только для динамического массива тогда  data  на самом деле является указателем на первый байт пакета, поэтому это будет работать: 

     package: = PPacket (data); // только для динамического массива тогда  data  на самом деле является указателем на первый байт пакета, поэтому это будет работать: 

     package: = PPacket (data); // только для динамического массива
    

    Но если данные являются не динамическим массивом, то это приведение типа будет недействительным. Вместо этого вам нужно будет преобразовать указатель в data , например:

     packet: = PPacket (@data); // только для статического массива
    

    Это не сработает, если это динамический массив. Первый код будет работать в обоих случаях. Но если у вас включена проверка диапазона (а вы, вероятно, должны это сделать), то я думаю, что первый код вызовет исключение, если data является динамическим массивом нулевой длины, поэтому будьте осторожны.


Если вы хотите чтобы вместо этого перейти по маршруту C #, где вы копируете байты из массива в отдельную переменную TPacket , я бы использовал это:

var
  packet: TPacket;

// Source param comes first. Params are passed by
// reference automatically.
Move(data[0], packet, SizeOf(packet));

Вам нужно убедиться, что data содержит достаточно байтов для заполнения всего значения TPacket . TPacket лучше не содержать никаких типов, управляемых компилятором, таких как строка , вариант , IUnknown или типы динамического массива. Ни приведение типов указателя, ни Move в этом случае не работают должным образом.

3
ответ дан 14 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: