将代码从C转换为Delphi(使用DLL)

问题描述 投票:1回答:2

我需要您的帮助;)。尝试使用SDR接收器(刀片RF)。我有dll(bladeRF.dll)。我在C上有一些代码(结构,枚举和函数)。C上的代码:

  typedef enum {
    BLADERF_BACKEND_ANY, 
    BLADERF_BACKEND_LINUX, 
    BLADERF_BACKEND_LIBUSB, 
    BLADERF_BACKEND_CYPRESS, 
    BLADERF_BACKEND_DUMMY = 100, 
   } bladerf_backend;

#define BLADERF_DESCRIPTION_LENGTH 33
#define BLADERF_SERIAL_LENGTH 33

struct bladerf_devinfo {
  bladerf_backend backend; 
  char serial[BLADERF_SERIAL_LENGTH]; 
  uint8_t usb_bus; 
  uint8_t usb_addr; 
  unsigned int instance; 
  char manufacturer[BLADERF_DESCRIPTION_LENGTH];
  char product[BLADERF_DESCRIPTION_LENGTH]; 
};

int CALL_CONV bladerf_get_device_list(struct bladerf_devinfo **devices);

我需要在Delphi(Embarcadero 10.3)上转换此代码。你能帮助我吗?我在Delphi上的代码:

Bladerf_Backend = (BLADERF_BACKEND_ANY,  BLADERF_BACKEND_LINUX,  BLADERF_BACKEND_LIBUSB,  BLADERF_BACKEND_CYPRESS,  BLADERF_BACKEND_DUMMY = 100);

PDevices = ^TDevices;
TDevices = record
  backend  : Bladerf_Backend;
  serial   : PAnsiChar;
  usb_bus  : Byte;
  usb_addr : Byte;
  instance : Integer;
  manufacturer :PAnsiChar;
  product :PAnsiChar;
end;

bladerf_get_device_list: function(point: PDevices): integer; cdecl;

//Try to execute
procedure TForm1.Button1Click(Sender: TObject);
var
  myblade : TDevices;
  pointer : PDevices;
begin
  pointer := @myblade;
  dongle_count:= bladerf_get_device_list(pointer);
  myblade := pointer^;
  Memo1.Lines.Add(myblade.serial);
  Memo1.Lines.Add(myblade.manufacturer);
  Memo1.Lines.Add(myblade.product);
end;

函数返回值(1)。但是记录具有错误值。需要你的帮助。谢谢。

c delphi dll
2个回答
1
投票

我不会在这里给出完整的答案,但有些要素可以为您提供帮助。代码有几个问题。

该记录应称为TDevice(而不是TDevices),因为它代表单个设备。它应该为具有正确大小的字符串(serialmanufacturerproduct)嵌入缓冲区;放置指针(PAnsiChar)无效。

bladerf_get_device_list()将指针指向TDevice的指针。那不是你给的。

bladerf_get_device_list()分配TDevice的数组并返回其大小。您应该检查返回的值。使用完数组后,应使用bladerf_free_device_list()释放它。


0
投票

您对char[]数组的翻译是错误的。需要将它们声明为array[0..high] of AnsiChar固定数组,而不是PAnsiChar指针。

而且,您对bladerf_get_device_list()的声明是错误的。 devices参数是一个输出参数,它会向您返回指向设备数组的指针,因此该函数必须能够更改您为其提供的指针,这意味着该参数必须声明为var或指针类型的out。否则,您将其声明为输入参数,并且该函数无法在运行时更改其值。

此外,使用列表完成后,请不要忘记拨打bladerf_free_device_list()

C语言的A literal翻译看起来像这样:

type
  bladerf_backend = (
    BLADERF_BACKEND_ANY, 
    BLADERF_BACKEND_LINUX, 
    BLADERF_BACKEND_LIBUSB, 
    BLADERF_BACKEND_CYPRESS, 
    BLADERF_BACKEND_DUMMY = 100, 
  );

const
  BLADERF_DESCRIPTION_LENGTH = 33;
  BLADERF_SERIAL_LENGTH = 33;

type
  pbladerf_devinfo = ^bladerf_devinfo;
  bladerf_devinfo = record
    backend: bladerf_backend; 
    serial: array[0..BLADERF_SERIAL_LENGTH-1] of AnsiChar; 
    usb_bus: UInt8;
    usb_addr: UInt8; 
    instance: UInt32; 
    manufacturer: array[0..BLADERF_DESCRIPTION_LENGTH-1] of AnsiChar;
    product: array[0..BLADERF_DESCRIPTION_LENGTH-1] of AnsiChar; 
  end;

const
  libbladeRF = 'libbladeRF.dll'; // or whatever the actual DLL filename is...

function bladerf_get_device_list(out devices: pbladerf_devinfo): Int32; cdecl; external libbladeRF;

procedure bladerf_free_device_list(devices: pbladerf_devinfo); cdecl; external libbladeRF;

然后您可以像这样使用它:

{$POINTERMATH ON}
procedure TForm1.Button1Click(Sender: TObject);
var
  devices: pbladerf_devinfo;
  dongle_count, i: Int32;
begin
  dongle_count := bladerf_get_device_list(devices);
  if dongle_count < 0 then
    // error handling ...
  try
    for i := 0 to dongle_count-1 do
    begin
      Memo1.Lines.Add(String(devices[i].serial));
      Memo1.Lines.Add(String(devices[i].manufacturer));
      Memo1.Lines.Add(String(devices[i].product));
    end;
  finally
    bladerf_free_device_list(devices);
  end;
end;

或者:

procedure TForm1.Button1Click(Sender: TObject);
var
  devices, device: pbladerf_devinfo;
  dongle_count, i: Int32;
begin
  dongle_count := bladerf_get_device_list(devices);
  if dongle_count < 0 then
    // error handling ...
  try
    device := devices;
    for i := 0 to dongle_count-1 do
    begin
      Memo1.Lines.Add(String(device^.serial));
      Memo1.Lines.Add(String(device^.manufacturer));
      Memo1.Lines.Add(String(device^.product));
      Inc(device);
    end;
  finally
    bladerf_free_device_list(devices);
  end;
end;
© www.soinside.com 2019 - 2024. All rights reserved.