我需要您的帮助;)。尝试使用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)。但是记录具有错误值。需要你的帮助。谢谢。
我不会在这里给出完整的答案,但有些要素可以为您提供帮助。代码有几个问题。
该记录应称为TDevice
(而不是TDevices
),因为它代表单个设备。它应该为具有正确大小的字符串(serial
,manufacturer
,product
)嵌入缓冲区;放置指针(PAnsiChar
)无效。
bladerf_get_device_list()
将指针指向TDevice
的指针。那不是你给的。
bladerf_get_device_list()
分配TDevice
的数组并返回其大小。您应该检查返回的值。使用完数组后,应使用bladerf_free_device_list()
释放它。
您对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;