我正在編寫一個C#應用程序,它將調用在Delphi中編寫的DLL。我有Delphi DLL的源代碼。我想從C#發送一個二維數組到DLL,並且該DLL創建另一個二維數組並將其發送回C#代碼。我怎樣才能做到這一點?如何從C#應用程序向Delphi DLL發送和接收二維數組?
回答
我寫過一些二維數組的示例代碼。這有點麻煩,因爲編組人不會自然處理二維數組。相反,我選擇平坦化數組,即將它們編組爲一維數組。這不會有很好的性能特點,但對您而言可能並不重要。只有你可以知道這一點。
的Delphi
library mydll;
var
arr: array of array of Double;
procedure ManagedToNative(RowCount, ColCount: Integer; Values: PDouble); stdcall;
var
r, c: Integer;
begin
SetLength(arr, RowCount, ColCount);
for r := 0 to RowCount-1 do begin
for c := 0 to ColCount-1 do begin
arr[r,c] := Values^;
inc(Values);
end;
end;
end;
procedure NativeToManaged(out RowCount, ColCount: Integer; Values: PDouble); stdcall;
var
r, c: Integer;
begin
RowCount := Length(arr);
if RowCount>0 then begin
ColCount := Length(arr[0]);
end else begin
ColCount := 0;
end;
if Assigned(Values) then begin
for r := 0 to RowCount-1 do begin
for c := 0 to ColCount-1 do begin
Values^ := arr[r,c];
inc(Values);
end;
end;
end;
end;
exports
ManagedToNative,
NativeToManaged;
begin
end.
C#
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport(@"mydll.dll")]
private static extern void ManagedToNative(int RowCount, int ColCount, double[] Values);
[DllImport(@"mydll.dll")]
private static extern void NativeToManaged(out int RowCount, out int ColCount, double[] Values);
static double[] Flattened(int RowCount, int ColCount, double[,] arr)
{
double[] result = new double[RowCount*ColCount];
int i = 0;
for (int r = 0; r < RowCount; r++)
for (int c = 0; c < ColCount; c++)
{
result[i] = arr[r,c];
i++;
}
return result;
}
static double[,] Expanded(int RowCount, int ColCount, double[] arr)
{
double[,] result = new double[RowCount,ColCount];
int i = 0;
for (int r = 0; r < RowCount; r++)
for (int c = 0; c < ColCount; c++)
{
result[r,c] = arr[i];
i++;
}
return result;
}
static void Main(string[] args)
{
const int RowCount = 6;
const int ColCount = 9;
double[,] arr = new double[RowCount,ColCount];
for (int r = 0; r < RowCount; r++)
for (int c = 0; c < ColCount; c++)
arr[r,c] = r*c;
ManagedToNative(RowCount, ColCount, Flattened(RowCount, ColCount, arr));
int myRowCount, myColCount;
NativeToManaged(out myRowCount, out myColCount, null);
double[] flat = new double[myRowCount * myColCount];
NativeToManaged(out myRowCount, out myColCount, flat);
double[,] expanded = Expanded(myRowCount, myColCount, flat);
for (int r = 0; r < RowCount; r++)
for (int c = 0; c < ColCount; c++)
System.Console.WriteLine(arr[r, c] - expanded[r, c]);
}
}
}
的代碼通過從C#到Delphi的二維陣列,其中它被存儲。然後C#代碼要求返回。 WriteLine()
語句顯示返回的值與傳遞的值相同。
我已安排NativeToManaged()
返回數組的維數,即使此代碼已經知道它們。實際上,你的C#代碼很可能想要問Delphi代碼的數組大小,以便它可以分配內存來存儲值。
我不會繼續談論爲什麼我做了某些事情。從以前的問題,我認爲你有足夠的專業知識來解決這個代碼。如果您有任何問題,請留下評論,我會盡我所能來解決一些問題!
@user你還對這個問題感興趣嗎? – 2011-05-16 08:56:05
我已經實現了我的系統,它運行良好。謝謝 – mans 2011-05-16 14:20:40
我想你可以在如XML或其他格式的傳輸數據,然後在DLL Delphi應用程序或.NET
感謝您的回覆。我認爲這不是一個優化的靈魂人物。有沒有更好的方法? – mans 2011-05-13 09:23:52
甲函數調用反序列化出的C#是可能的,則可以傳遞參數。你的二維數組是一個類型或類,它可以作爲參數傳遞。這裏是一個很好的解釋瞭如何調用德爾福DLL出的C#:
http://tek-tips.com/faqs.cfm?fid=7416
這個例子通過「PChar類型」的其他類型的DLL。你也可以傳遞指向你的數組的指針。
數組的內容是什麼? – 2011-05-13 15:43:56
@user我可以爲你解答這個問題(目前的兩個答案都不適合你),但你需要回答我的問題。我的答案將是另一個P/Invoke,StructureToPtr類型的答案,非常類似於您的上一個問題。但爲了給你很好的示例代碼,我需要知道數組元素是什麼類型。 – 2011-05-14 10:17:05
它們是雙重的。你爲什麼稱它爲PInvoke?我認爲,編寫一個具有多種功能的庫可以幫助從C#代碼向/從delphi dll發送和接收不同類型的變量。 – mans 2011-05-14 11:36:37