2016-08-05 17 views
0

受け取ったI/Qデータを配信するためにコールバックを与える必要があるソフトウェア定義レシーバDLLにインターフェイス接続しようとしています。DelphiでDLLコールバックを実装する

私はDLLを正常に呼び出すことができますが、コールバックをコーディングする方法を理解することはできません。

これは、メインモジュールの一部です:

uses 
    uReceiverHackRFDLLWrapper; 

procedure TForm1.btnIDClick(Sender: TObject); 
var 
    strptr: PAnsiChar; 
begin 
    hackrf_board_init(); 
    strptr := hackrf_board_id_name(0); 
    lblName.Caption := 'Name: ' + strptr; 
end; 

これは、DLLのラッパーです:

unit uReceiverHackRFDLLWrapper; 

interface 

uses Windows, uSETITypes, sysutils; 

{$MINENUMSIZE 4} 

type 
    // Trtlsdr_read_async_cb_t = procedure(buf: PAnsiChar; len: UINT32; ctx: Pointer); 
    // [UnmanagedFunctionPointer(CallingConvention.StdCall)] 
    // public unsafe delegate int hackrf_sample_block_cb_fn(hackrf_transfer* ptr); /* Return 0 if OK or -1 if error to stop */ 
    THackrf_sample__block_cb_fn = function(var hackrf_transfer: Pointer): integer; 

function hackrf_board_id_name(index: integer): Pointer; stdcall; 
function hackrf_board_init(): integer; stdcall; 
function hackrf_open(var dev: THackRF_dev): integer; stdcall; 

function hackrf_start_rx(dev: THackRF_dev; cb: THackrf_sample__block_cb_fn; rx_ctx: Pointer): integer; 

implementation 

var 
    DLLLoaded: Boolean = False; 
    SaveExit: Pointer; 
    DLLHandle: THandle; 

function SampleCallBack(var hackrf_transfer: Pointer): integer; 
var 
    i: integer; 
begin 
    i := 12345; 
end; 

function GetModuleFileNameStr(Instance: THandle): string; 
var 
    buffer: array [0 .. MAX_PATH] of Char; 
begin 
    GetModuleFileName(Instance, buffer, MAX_PATH); 

    Result := extractfilepath(buffer); 
end; 

function hackrf_board_id_name; external 'libhackrf.dll' name 'hackrf_board_id_name'; 
function hackrf_board_init; external 'libhackrf.dll' name 'hackrf_init'; 
function hackrf_open; external 'libhackrf.dll' name 'hackrf_open'; 

// [DllImport(LibHackRF, EntryPoint = "hackrf_start_rx", CallingConvention = CallingConvention.StdCall)] 
// public static extern int hackrf_start_rx(IntPtr dev, hackrf_sample_block_cb_fn cb, IntPtr rx_ctx); 
function hackrf_start_rx; external 'libhackrf.dll' name 'hackrf_start_rx'; 

initialization 

DLLHandle := LoadLibrary('libhackrf.dll'); 

end. 

誰もが、私が使用することができます。このコールバックの簡単な例がありますか?

+0

これは理解するのではなく難しいです。あなたがそれを切ることができるなら、それは良いでしょう。あなたはコールバックのための呼び出し規約に対処していません。私たちはいくつかのタイプしか見ることができません。 –

+0

すべてのDll関数がstdcallなので、 – Sami

+0

の質問が不明です。コールバックもstdcallにする必要がありますか? – Fritzw

答えて

4

libHackRF API documentationおよびsource codeに基づいて、ラッパーユニットにはいくつかのエラーがあります。 DLL関数の最初の

、すべてがWindows上の呼び出し規約、ないstdcallとしてcdeclを使用しています。

第2に、hackrf_start_rx()関数は呼び出し規約で宣言されていないため、Delphiのデフォルトのregister規約を使用しています。 THackrf_sample__block_cb_fnと同じです。宣言にcdeclを追加する必要があります。 THackrf_sample__block_cb_fnhackrf_transferパラメータのvar Pointerを用い

第三に、実際のhackrf_sample_block_cb_fnコールバックタイプの署名と一致しません。

hackrf_transfer自体はこのような何か(それはすでに uSETITypesユニットで宣言されていないと仮定して)宣言する必要があり
THackrf_sample__block_cb_fn = function(var ptr: hackrf_transfer): integer; cdecl; 

:やった

type 
    phackrf_device = ^hackrf_device; 
    hackrf_device = record 
    end; 

    ... 

    hackrf_transfer = record 
    device: phackrf_device; 
    buffer: PByte; 
    buffer_length: Integer; 
    valid_length: Integer; 
    rx_ctx: Pointer; 
    tx_ctx: Pointer; 
    end; 

を正しいコールバックの宣言は、より多くの代わりに、このようにする必要がありますTrtlsdr_read_async_cb_tはどこから来たのですか?これはAPIの一部ではありません。

今言ったことのすべてを、適切なラッパーユニットではなく、より次のようになります。

NOW
unit uHackRF; 

interface 

{$MINENUMSIZE 4} 

type 
    hackrf_error = (
    HACKRF_SUCCESS = 0, 
    HACKRF_TRUE = 1, 
    HACKRF_ERROR_INVALID_PARAM = -2, 
    HACKRF_ERROR_NOT_FOUND = -5, 
    HACKRF_ERROR_BUSY = -6, 
    HACKRF_ERROR_NO_MEM = -11, 
    HACKRF_ERROR_LIBUSB = -1000, 
    HACKRF_ERROR_THREAD = -1001, 
    HACKRF_ERROR_STREAMING_THREAD_ERR = -1002, 
    HACKRF_ERROR_STREAMING_STOPPED = -1003, 
    HACKRF_ERROR_STREAMING_EXIT_CALLED = -1004, 
    HACKRF_ERROR_OTHER = -9999, 
); 

    hackrf_board_id = (
    BOARD_ID_JELLYBEAN = 0, 
    BOARD_ID_JAWBREAKER = 1, 
    BOARD_ID_HACKRF_ONE = 2, 
    BOARD_ID_INVALID = 0xFF, 
); 

    hackrf_usb_board_id = (
    USB_BOARD_ID_JAWBREAKER = 0x604B, 
    USB_BOARD_ID_HACKRF_ONE = 0x6089, 
    USB_BOARD_ID_RAD1O = 0xCC15, 
    USB_BOARD_ID_INVALID = 0xFFFF, 
); 

    rf_path_filter = (
    RF_PATH_FILTER_BYPASS = 0, 
    RF_PATH_FILTER_LOW_PASS = 1, 
    RF_PATH_FILTER_HIGH_PASS = 2, 
); 

    transceiver_mode_t = (
    TRANSCEIVER_MODE_OFF = 0, 
    TRANSCEIVER_MODE_RX = 1, 
    TRANSCEIVER_MODE_TX = 2, 
    TRANSCEIVER_MODE_SS = 3, 
    TRANSCEIVER_MODE_CPLD_UPDATE = 4 
); 

    phackrf_device = ^hackrf_device; 
    hackrf_device = record 
    end; 

    hackrf_transfer = record 
    device: phackrf_device; 
    buffer: PByte; 
    buffer_length: Integer; 
    valid_length: Integer; 
    rx_ctx: Pointer; 
    tx_ctx: Pointer; 
    end; 

    read_partid_serialno_t = record 
    part_id: array[0..1] of UInt32; 
    serial_no: array[0..3] of UInt32; 
    end; 

    hackrf_device_list = record 
    serial_numbers: PPAnsiChar; 
    usb_board_ids: ^hackrf_usb_board_id; 
    usb_device_index: PInteger; 
    devicecount: Integer; 

    usb_devices: PPointer; 
    usb_devicecount: Integer; 
    end; 

    hackrf_device_list_t = hackrf_device_list; 
    phackrf_device_list_t = ^hackrf_device_list_t; 

    hackrf_sample_block_cb_fn = function(var transfer: hackrf_transfer): Integer; cdecl; 

function hackrf_init: Integer; cdecl; 
function hackrf_exit: Integer; cdecl; 

function hackrf_device_list: phackrf_device_list_t; cdecl; 
function hackrf_device_list_open(list: phackrf_device_list_t; idx: Integer; var device: phackrf_device): Integer; cdecl; 
procedure hackrf_device_list_free(list: phackrf_device_list_t); cdecl; 

function hackrf_open(var device: phackrf_device): Integer; cdecl; 
function hackrf_open_by_serial(const desired_serial_number: PAnsiChar; var device: phackrf_device): Integer; cdecl;; 
function hackrf_close(device: phackrf_device): Integer; cdecl; 

function hackrf_start_rx(device: phackrf_device; callback: hackrf_sample_block_cb_fn; rx_ctx: Pointer): Integer; cdecl; 
function hackrf_stop_rx(device: phackrf_device): Integer; cdecl; 

function hackrf_start_tx(device: phackrf_device; callback: hackrf_sample_block_cb_fn; tx_ctx: Pointer): Integer; cdecl; 
function hackrf_stop_tx(device: phackrf_device): Integer; cdecl; 

{ return HACKRF_TRUE if success } 
function hackrf_is_streaming(device: phackrf_device): Integer; cdecl; 

function hackrf_max2837_read(device: phackrf_device; register_number: UInt8; var value: UInt16): Integer; cdecl; 
function hackrf_max2837_write(device: phackrf_device; register_number: UInt8; value: UInt16): Integer; cdecl; 

function hackrf_si5351c_read(device: phackrf_device; register_number: UInt16; var value: UInt16): Integer; cdecl; 
function hackrf_si5351c_write(device: phackrf_device; register_number: UInt16; value: UInt16): Integer; cdecl; 

function hackrf_set_baseband_filter_bandwidth(device: phackrf_device; const bandwidth_hz: UInt32): Integer; cdecl; 

function hackrf_rffc5071_read(device: phackrf_device; register_number: UInt8; var value: UInt16): Integer; cdecl; 
function hackrf_rffc5071_write(device: phackrf_device; register_number: UInt8; value: UInt16): Integer; cdecl; 

function hackrf_spiflash_erase(device: phackrf_device): Integer; cdecl; 
function hackrf_spiflash_write(device: phackrf_device; const address: UInt32; const length: UInt16; const data: PByte): Integer; cdecl; 
function hackrf_spiflash_read(device: phackrf_device; const address: UInt32; const length: UInt16; data: PByte): Integer; cdecl; 

{ device will need to be reset after hackrf_cpld_write } 
function hackrf_cpld_write(device: phackrf_device; const data: PByte; const total_length: UInt32): Integer; cdecl; 

function hackrf_board_id_read(device: phackrf_device; var value: UInt8): Integer; cdecl; 
function hackrf_version_string_read(device: phackrf_device; version: PAnsiChar; length: UInt8): Integer; cdecl; 

function hackrf_set_freq(device: phackrf_device; const freq_hz: UInt64): Integer; cdecl; 
function hackrf_set_freq_explicit(device: phackrf_device; const if_freq_hz, lo_freq_hz: UInt64; const path: rf_path_filter): Integer; cdecl; 

{ currently 8-20Mhz - either as a fraction, i.e. freq 20000000hz divider 2 -> 10Mhz or as plain old 10000000hz (double) 
    preferred rates are 8, 10, 12.5, 16, 20Mhz due to less jitter } 
function hackrf_set_sample_rate_manual(device: phackrf_device; const freq_hz, divider: UInt32): Integer; cdecl; 
function hackrf_set_sample_rate(device: phackrf_device; const freq_hz: Double): Integer; cdecl; 

{ external amp, bool on/off } 
function hackrf_set_amp_enable(device: phackrf_device; const value: UInt8): Integer; cdecl; 

function hackrf_board_partid_serialno_read(device: phackrf_device; var read_partid_serialno: read_partid_serialno_t): Integer; cdecl; 

{ range 0-40 step 8d, IF gain in osmosdr } 
function hackrf_set_lna_gain(device: phackrf_device; value: UInt32): Integer; cdecl; 

{ range 0-62 step 2db, BB gain in osmosdr } 
function hackrf_set_vga_gain(device: phackrf_device; value: UInt32): Integer; cdecl; 

{ range 0-47 step 1db } 
function hackrf_set_txvga_gain(device: phackrf_device; value: UInt32): Integer; cdecl; 

{ antenna port power control } 
function hackrf_set_antenna_enable(device: phackrf_device; const value: UInt8): Integer; cdecl; 

function hackrf_error_name(errcode: hackrf_error): PAnsiChar; cdecl; 
function hackrf_board_id_name(board_id: hackrf_board_id): PAnsiChar; cdecl; 
function hackrf_usb_board_id_name(usb_board_id: hackrf_usb_board_id): PAnsiChar; cdecl; 
function hackrf_filter_path_name(const path: rf_path_filter): PAnsiChar; cdecl; 

{ Compute nearest freq for bw filter (manual filter) } 
function hackrf_compute_baseband_filter_bw_round_down_lt(const bandwidth_hz: UInt32): UInt32; cdecl; 
{ Compute best default value depending on sample rate (auto filter) } 
function hackrf_compute_baseband_filter_bw(const bandwidth_hz: UInt32): UInt32; 

implementation 

const 
    LibHackRF = 'libhackrf.dll'; 

function hackrf_init; external LibHackRF name 'hackrf_init'; 
function hackrf_exit; external LibHackRF name 'hackrf_exit'; 

function hackrf_device_list; external LibHackRF name 'hackrf_device_list'; 
function hackrf_device_list_open; external LibHackRF name 'hackrf_device_list_open'; 
procedure hackrf_device_list_free; external LibHackRF name 'hackrf_device_list_free'; 

function hackrf_open; external LibHackRF name 'hackrf_open'; 
function hackrf_open_by_serial; external LibHackRF name 'hackrf_open_by_serial'; 
function hackrf_close; external LibHackRF name 'hackrf_close'; 

function hackrf_start_rx; external LibHackRF name 'hackrf_start_rx'; 
function hackrf_stop_rx; external LibHackRF name 'hackrf_stop_rx'; 

function hackrf_start_tx; external LibHackRF name 'hackrf_start_tx'; 
function hackrf_stop_tx; external LibHackRF name 'hackrf_stop_tx'; 

function hackrf_is_streaming; external LibHackRF name 'hackrf_is_streaming'; 

function hackrf_max2837_read; external LibHackRF name 'hackrf_max2837_read'; 
function hackrf_max2837_write; external LibHackRF name 'hackrf_max2837_write'; 

function hackrf_si5351c_read; external LibHackRF name 'hackrf_si5351c_read'; 
function hackrf_si5351c_write; external LibHackRF name 'hackrf_si5351c_write'; 

function hackrf_set_baseband_filter_bandwidth; external LibHackRF name 'hackrf_set_baseband_filter_bandwidth'; 

function hackrf_rffc5071_read; external LibHackRF name 'hackrf_rffc5071_read'; 
function hackrf_rffc5071_write; external LibHackRF name 'hackrf_rffc5071_write'; 

function hackrf_spiflash_erase; external LibHackRF name 'hackrf_spiflash_erase'; 
function hackrf_spiflash_write; external LibHackRF name 'hackrf_spiflash_write'; 
function hackrf_spiflash_read; external LibHackRF name 'hackrf_spiflash_read'; 

function hackrf_cpld_write; external LibHackRF name 'hackrf_cpld_write'; 

function hackrf_board_id_read; external LibHackRF name 'hackrf_board_id_read'; 
function hackrf_version_string_read; external LibHackRF name 'hackrf_version_string_read'; 

function hackrf_set_freq; external LibHackRF name 'hackrf_set_freq'; 
function hackrf_set_freq_explicit; external LibHackRF name 'hackrf_set_freq_explicit'; 

function hackrf_set_sample_rate_manual; external LibHackRF name 'hackrf_set_sample_rate_manual'; 
function hackrf_set_sample_rate; external LibHackRF name 'hackrf_set_sample_rate'; 

function hackrf_set_amp_enable; external LibHackRF name 'hackrf_set_amp_enable'; 

function hackrf_board_partid_serialno_read; external LibHackRF name 'hackrf_board_partid_serialno_read'; 

function hackrf_set_lna_gain; external LibHackRF name 'hackrf_set_lna_gain'; 

function hackrf_set_vga_gain; external LibHackRF name 'hackrf_set_vga_gain'; 

function hackrf_set_txvga_gain; external LibHackRF name 'hackrf_set_txvga_gain'; 

function hackrf_set_antenna_enable; external LibHackRF name 'hackrf_set_antenna_enable'; 

function hackrf_error_name; external LibHackRF name 'hackrf_error_name'; 
function hackrf_board_id_name; external LibHackRF name 'hackrf_board_id_name'; 
function hackrf_usb_board_id_name; external LibHackRF name 'hackrf_usb_board_id_name'; 
function hackrf_filter_path_name; external LibHackRF name 'hackrf_filter_path_name'; 

function hackrf_compute_baseband_filter_bw_round_down_lt; external LibHackRF name 'hackrf_compute_baseband_filter_bw_round_down_lt'; 
function hackrf_compute_baseband_filter_bw; external LibHackRF name 'hackrf_compute_baseband_filter_bw'; 

end. 

を、あなたはコールバックを書くことができます

​​
+0

レミー - あなたのご意見ありがとうございます。 API呼び出しを翻訳することは、難しいことではありません。私は1つの問題を抱えていました。 はこのようなデバイスリストの見てはいけない: hackrf_device_list_t =その後、レコード // hackrf_device_list_t = hackrf_device_list。 –

+0

@SetiNetあなたはそうすることができます。私が示したことは*リテラル*翻訳です。 APIは実際の 'hackrf_device_list'構造体を宣言し、それに' hackrf_device_list_t'エイリアスを宣言します。だから私は同じことをしました。 –

+0

それは私を混乱させる部分です。構造体のAPI名はhackrf_device_list_tです。そのエイリアスはまったく見つかりません。 –

関連する問題