2011-05-13 50 views
0

我正在編寫一個C#應用程序,它將調用在Delphi中編寫的DLL。我有Delphi DLL的源代碼。我想從C#發送一個二維數組到DLL,並且該DLL創建另一個二維數組並將其發送回C#代碼。我怎樣才能做到這一點?如何從C#應用程序向Delphi DLL發送和接收二維數組?

+0

數組的內容是什麼? – 2011-05-13 15:43:56

+0

@user我可以爲你解答這個問題(目前的兩個答案都不適合你),但你需要回答我的問題。我的答案將是另一個P/Invoke,StructureToPtr類型的答案,非常類似於您的上一個問題。但爲了給你很好的示例代碼,我需要知道數組元素是什麼類型。 – 2011-05-14 10:17:05

+0

它們是雙重的。你爲什麼稱它爲PInvoke?我認爲,編寫一個具有多種功能的庫可以幫助從C#代碼向/從delphi dll發送和接收不同類型的變量。 – mans 2011-05-14 11:36:37

回答

1

我寫過一些二維數組的示例代碼。這有點麻煩,因爲編組人不會自然處理二維數組。相反,我選擇平坦化數組,即將它們編組爲一維數組。這不會有很好的性能特點,但對您而言可能並不重要。只有你可以知道這一點。

的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代碼的數組大小,以便它可以分配內存來存儲值。

我不會繼續談論爲什麼我做了某些事情。從以前的問題,我認爲你有足夠的專業知識來解決這個代碼。如果您有任何問題,請留下評論,我會盡我所能來解決一些問題!

+0

@user你還對這個問題感興趣嗎? – 2011-05-16 08:56:05

+0

我已經實現了我的系統,它運行良好。謝謝 – mans 2011-05-16 14:20:40

-1

我想你可以在如XML或其他格式的傳輸數據,然後在DLL Delphi應用程序或.NET

+0

感謝您的回覆。我認爲這不是一個優化的靈魂人物。有沒有更好的方法? – mans 2011-05-13 09:23:52

0

甲函數調用反序列化出的C#是可能的,則可以傳遞參數。你的二維數組是一個類型或類,它可以作爲參數傳遞。這裏是一個很好的解釋瞭如何調用德爾福DLL出的C#:

http://tek-tips.com/faqs.cfm?fid=7416

這個例子通過「PChar類型」的其他類型的DLL。你也可以傳遞指向你的數組的指針。