2015-05-12 44 views
2

我想在C#中使用delphi數組函數。不能在C#數組中返回delphi數組

我的Delphi代碼:

TIntegerArray = array of integer; 
    function Testarray(): TIntegerArray stdcall; export; 
    var 
     res: TIntegerArray2; 
    begin 
     SetLength(res, 10); 
     res[5] := 55; 
     Result := res; 
    end; 
    exports Testarray; 

C#代碼:

[DllImport("GitaTele.dll", CallingConvention = CallingConvention.StdCall)] 
public static extern int[] Testarray(); 

告訴我錯誤: 不能元帥返回值「:無效的託管/非託管類型組合。

+1

在Delphi中你可以同時在C#中嘗試這個映射到'INT []'返回一個特定的類型'TIntegerArray2'。 Howe是否應該工作? –

+0

你不能直接編組數組**作爲retun值**。即使可以,誰會釋放Delphy爲該陣列分配的內存? – xanatos

+0

謝謝。 edited.my代碼超過: TIntegerArray =整數數組; TIntegerArray2 =整數數組; –

回答

3

Delphi動態數組不是有效的互操作類型。你需要調用者分配數組,然後讓被調用者填充它。

procedure PopulateArray(arr: PInteger; var len: Integer); stdcall; 
var 
    i: Integer; 
    returnArray: TArray<Integer>; 
begin 
    returnArray := GetArray; 
    len := Min(len, Length(returnArray)); 
    for i := 0 to len - 1 do 
    begin 
    arr^ := returnArray[i]; 
    inc(arr); 
    end; 
end; 

請注意export已經沒有意義,被忽略,並且應爲簡單起見被移除。

從C#調用代碼:

[DllImport("...", CallingConvention = CallingConvention.StdCall)] 
public static extern void PopulateArray(
    [In, Out] 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] 
    int[] arr, 
    ref int len 
); 

.... 

int[] arr = new int[50]; 
int len = arr.Length; 
PopulateArray(arr, ref len); 
// len now contains actual length 
+0

爲什麼它需要整個'MarshalAs'?他不能將數組直接編組到一個'PInteger',那是一個'int *'? – xanatos

+0

您可以不用'MarshalAs',但它可以讓編組人員優化編組。另一方面,由於這個例子是blittable,那麼編組人員將只是釘住數組。所以從這個意義上說,'MarshalAs'沒有任何用處。 –

+0

@DavidHeffernan'MarshalAs(MarshalAs(''你在代碼中加倍了'MarshalAs'。 – xanatos