Reputation: 13
I need your help ;). Try to work with SDR-receiver (blade RF). I have dll (bladeRF.dll). I have some code on C (struct, enum and function). Code on 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);
I need transform this code on Delphi (Embarcadero 10.3). Can you help me? My code on 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;
Function return value (1). But record has mistake values. Need your help. Thanks.
Upvotes: 0
Views: 169
Reputation: 598299
Your translation of the char[]
arrays is wrong. They need to be declared as array[0..high] of AnsiChar
fixed arrays, not as PAnsiChar
pointers.
Also, your declaration of bladerf_get_device_list()
is wrong. The devices
parameter is an output parameter, it returns to you a pointer to an array of devices, so the function needs to be able to alter a pointer that you give it, which means the parameter must be declared as either var
or out
of a pointer type. Without that, you are declaring devices
as an input parameter instead, and thus the function can't alter your pointer.
Also, don't forget to call bladerf_free_device_list()
when you are done using the list.
A literal translation of the C code would look more like this instead:
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;
And then you can use it like this:
{$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;
Alternatively:
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;
Upvotes: 2
Reputation: 18260
I won't give a complete answer here but some elements to help you. There are several issues with the code.
The record should be called TDevice
(not TDevices
) because it represents a single device.
It should embed buffers for the strings (serial
, manufacturer
, product
) with the correct sizes; putting pointers instead (PAnsiChar
) won't work.
bladerf_get_device_list()
takes a pointer to a pointer to a TDevice
. That's not what you give it.
bladerf_get_device_list()
allocates an array of TDevice
and returns its size. You should check the returned value. After you're done using the array, you should use bladerf_free_device_list()
to free it.
Upvotes: 2