Can anyone help me with translation of this struct

2019-07-20 05:24发布

问题:

I need help to transcribe a struct that has another nested struct to Delphi. Below is a struct:

#define CHANNEL_TAG_LENGTH 17
struct stChannelInfo
 {
  char ChannelTag[CHANNEL_TAG_LENGTH];  // Tag (máx 16 caracteres)
  char ChannelEnabled;  // Habilitado se diferente de "0"
 };

// Structure with information about channels
struct stChannel
 {
  int ChannelNumber;  // Número de canais no buffer
  struct stChannelInfo *ChannelInfo;  // Buffer com informações dos canais
 };

In Borland C + + 6, the example uses the following code to read the value of ChannelTag:

 stChannels = this->deviceInterface->LookForAvailableChannels(EdDirectorySource->Text.c_str(), iSn, dateTimeStart, dateTimeEnd);
 for(int i = 0; i < stChannels.ChannelNumber; i++)
 {
  CLbChannels->Items->Add(stChannels.ChannelInfo[i].ChannelTag);  // Add to list the values found
 }

I wish I could do the same in Delphi. How should I transcribe structs?

Thanks and sorry because English is not my native language

EDIT

I was wrong not to post what I had done on Delphi. Follow my attempt:

// record who receive the values 
type stChannelInfo = record
    ChannelTag : string[16];    
    ChannelEnabled : char ; 
end;

type stChannel = record
    ChannelNumber:integer;  // Númber of buffer channels
    ChannelInfo : ^stChannelInfo ;
end;

And so i tried to read :

 Var DadosCanais : stChannel;  // defined in var section of procedure onclick Button.

 DadosCanais:=LookForAvailableChannels (Pwidechar(dirroot) , sn , datepickerinicial.DateTime,datepickerfinal.DateTime);
 for i := 0 to (DadosCanais.ChannelNumber-1) do  
  begin  
   Showmessage(String(DadosCanais.ChannelInfo^.ChannelTag));
   inc(DadosCanais.ChannelInfo);
  end;

I get the record, but I can not correctly read ​​ChannelTag values. It seems that the size is incorrect, because the strings is truncated and always lose the first character of the name.

Maybe this clarify a little the question. Thanks again

SOLUTION

Following advice from Remy , i do this :

 sn:=strtoint(lstdirMaquinas.Items[lstdirMaquinas.Itemindex]);
 Dadoscanais := LookForAvailableChannels(PChar(dirroot) , sn , datepickerinicial.DateTime,datepickerfinal.DateTime);
 for i:=0 to DadosCanais.ChannelNumber-1 do
  begin
    ListboxChannel.Items.add(String(DadosCanais.ChannelInfo[i].ChannelTag));
  end;

For now this resolves my problem. Thanks all.

回答1:

{$POINTERMATH ON}

Type
  PstChannelInfo = ^stChannelInfo;
  stChannelInfo = record
    ChannelTag: array[0..CHANNEL_TAG_LENGTH-1] of AnsiChar;  // Tag (máx 16 caracteres)
    ChannelEnabled: AnsiChar;  // Habilitado se diferente de "0"
  end;

  // Structure with information about channels
  stChannel = record
    ChannelNumber: Integer;  // Número de canais no buffer
    ChannelInfo: PstChannelInfo;  // Buffer com informações dos canais
  end;

stChannels := Self.deviceInterface.LookForAvailableChannels(PChar(EdDirectorySource.Text), iSn, dateTimeStart, dateTimeEnd);
for i := 0 to stChannels.ChannelNumber-1 do begin
  CLbChannels.Items.Add(stChannels.ChannelInfo[i].ChannelTag);  // Add to list the values found
end;

Alternatively:

Type
  PstChannelInfo = ^stChannelInfo;
  stChannelInfo = record
    ChannelTag: array[0..CHANNEL_TAG_LENGTH-1] of AnsiChar;  // Tag (máx 16 caracteres)
    ChannelEnabled: AnsiChar;  // Habilitado se diferente de "0"
  end;

  // Structure with information about channels
  stChannel = record
    ChannelNumber: Integer;  // Número de canais no buffer
    ChannelInfo: PstChannelInfo;  // Buffer com informações dos canais
  end;

  PstChannelInfoList = ^TstChannelInfoList;
  TstChannelInfoList = [0..(MaxInt div SizeOf(stChannelInfo))-1] of stChannelInfo;

stChannels := Self.deviceInterface.LookForAvailableChannels(PChar(EdDirectorySource.Text), iSn, dateTimeStart, dateTimeEnd);
for i := 0 to stChannels.ChannelNumber-1 do begin
  CLbChannels.Items.Add(PstChannelInfoList(stChannels.ChannelInfo)^[i].ChannelTag);  // Add to list the values found
end;