我有一些用Delphi撰寫的函式,我需要通過DLL從其他編程語言(例如Python)訪問這些函式。Delphi函式將某種數字(整數或雙數)、陣列或Matrizes(陣列的陣列)作為輸入和回傳型別。
在Delphi中,用一個簡單的測驗函式來傳遞整數,效果非常好:
library Delphi_Library。
uses
System.SysUtils;
function AddIntegers(const _a, _b: integer): integer; stdcall;
begin; begin.
結果 := _a _b;
end;
exports
添加Integers。
beginend。
并從Python中呼叫它:
import ctypes
Dll = ctypes.WinDLL('Delphi_Library')
a = ctypes.c_int(5)
b = ctypes.c_int(7)
c = Dll.AddIntegers(a, b)
print(c)
然而,我不能直接將一個陣列傳遞給DLL,而是按照我的理解,我需要使用一個指向陣列的指標。另外,我不能使用一個陣列作為回傳型別,所以我想改變一個輸入陣列。作為測驗函式,我想寫一個小函式,它接收一個指向陣列array_in的指標和它的長度size_array_in作為輸入,并將另一個陣列array_out和它的大小size_array_out設為相同的值。它還將陣列的最后一個元素作為雙倍回傳。
我在Delphi中的代碼看起來像:
library Delphi_Library。
uses
System.SysUtils;
type
TArray = Array of Double。
PArray = ^TArray;
function ReturnArray(array_in。pointer; size_array_in: integer; array_out: pointer; size_array_out: integer): Double; stdcall;
var
i: 整數。
P_value: PDouble。
arr: TArray;
begin[/span
結果 := 0;
P_value := PDouble(array_in);
setlength(arr, size_array_out);
//arr := P_in^;
for i := 0 to size_array_in-1 do<
begin
arr[i] := P_value^;
inc(P_value)。
end;
array_out := @arr;
size_array_out := Length(arr);
end;
exports; exports.
回傳Array。
begin
end。
而在Python中
ReturnArray = Dll.ReturnArray
ReturnArray.restype = ctypes.c_double
ReturnArray.argtypes = ctypes.POINTER(ctypes.c_double*8), ctypes.c_int, ctypes.POINTER(ctypes.c_double*8), ctypes.c_int
data_in = (ctypes.c_double*8)(*range(32, 40)
data_out = (ctypes.c_double*8)(*range(8)
num_1 = 8
num_2 = 8 8
print('input', list(data_in), list(data_out)
retval = ReturnArray(data_in, num_1, data_out, num_2)
print('output'/span>, retval, list(data_in), list(data_out)
然而,在呼叫Delphi-DLL-函式后,我仍然得到相同的陣列/串列data_out。
那么,我如何將一個陣列或一個陣列的指標從其他編程語言決議為Delphi-Array?我的最終目標是寫一個介面,能夠使用一個定義為function AnyFunction(a: Array of Double; b: Array of Array of Double)的Delphi函式。任何支持呼叫C-DLLs的編程語言都可以使用Double的陣列。
uj5u.com熱心網友回復:
Delphi的動態陣列與其他編程語言/編譯器根本不兼容(除了C Builder)。 所以你需要只對原始指標進行操作。 在這種情況下,呼叫者需要分配兩個陣列并傳入它們的指標,然后Delphi代碼可以簡單地從一個陣列復制值到另一個陣列,例如:
library Delphi_Library。
uses
System.SysUtils, System.Math;
{$POINTERMATH ON}
function ReturnArray(array_in。PDouble; size_array_in: 整數。
array_out: PDouble; size_array_out: Integer): Integer; stdcall;
var
i, len: 整數。
begin
len := Min(size_array_in, size_array_out);
for i := 0 to len-1 do<
begin
array_out[i] := array_in[i];
//或者,如果{$POINTERMATH}在你的Delphi版本中不可用:
// array_out^ := array_in^;
//Inc(array_in);
// Inc(array_out);
end。
// Or simpler:
//Move(array_in^, array_out^, len * sizeof(Double));
結果 := len;
end。
exports
回傳Array。
begin
end。
ReturnArray = Dll.ReturnArray
ReturnArray.restype = ctypes.c_int
ReturnArray.argtypes = ctypes.POINTER(ctypes.c_double*8), ctypes.c_int, ctypes.POINTER(ctypes.c_double*8), ctypes.c_int
data_in = (ctypes.c_double*8)(*range(32, 40)
data_out = (ctypes.c_double*8)(*range(8)
num_1 = 8
num_2 = 8 8
print('input', list(data_in), list(data_out)
retval = ReturnArray(data_in, num_1, data_out, num_2)
print('output'/span>, retval, list(data_in), list(data_out)
我的最終目標是寫一個介面,能夠使用一個定義為function AnyFunction(a: Array of Double; b: Array of Array of Double)的Delphi函式。Array of Double從任何支持呼叫C-DLLs的編程語言中使用。
Delphi 開放陣列引數只不過是編譯器的魔法,用來隱藏一對引數,這些引數包括:
- 一個指向陣列第一元素的原始指標 。
- 陣列的最后一個索引(不是長度!)。
因此,舉例來說,上面的例子可以用開放的陣列引數來重寫,就像這樣:
library Delphi_Library。
uses
System.SysUtils, System.Math;
function ReturnArray(array_in: array of Double。
array_out: array of Double): Integer; stdcall;
var
i, len: 整數。
begin
len :=Min(Length(array_in), Length(array_out))。
for i := 0 to len-1 do<
begin
array_out[i] := array_in[i];
end;
// Or simpler:
//Move(array_in[0], array_out[0], len * sizeof(Double));
結果 := len;
end。
exports
回傳Array。
begin
end。
ReturnArray = Dll.ReturnArray
ReturnArray.restype = ctypes.c_int
ReturnArray.argtypes = ctypes.POINTER(ctypes.c_double*8), ctypes.c_int, ctypes.POINTER(ctypes.c_double*8), ctypes.c_int
data_in = (ctypes.c_double*8)(*range(32, 40)
data_out = (ctypes.c_double*8)(*range(8)
num_1 = 7 # NOT 8!
num_2 = 7 # NOT 8!
print('input', list(data_in), list(data_out)
retval = ReturnArray(data_in, num_1, data_out, num_2)
print('output'/span>, retval, list(data_in), list(data_out)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/316508.html
標籤:
上一篇:將一個通用型別的變數轉換為字串
