2017-09-22 34 views
0

我從Delphi2006用dll導出以下內容。如何marshall int從C#到德爾福

procedure ScSetMRStatus(StatusType: TStatusType; active_mr_ids: TLongIntArray; id_dst: Integer; id_src_list: TLongIntArray; IsComplete: Boolean); stdcall; export; 

其中TLongIntArray定義爲:

TLongIntArray = array of LongInt; 

和TStatusType只是一個枚舉:

TStatusType = (stPhysical, stMaster); 

現在我試圖調用從C#應用此方法。

[DllImport(DelphiDLLName, EntryPoint = "ScSetMRStatus", CallingConvention = CallingConvention.StdCall)] 
private static extern void ScSetMRStatus(
    Int32 statusType, 
    IntPtr activeMrIds, 
    Int32 IdDst, 
    IntPtr idSrcList, 
    [MarshalAs(UnmanagedType.U1)] bool isComplete); 

從C#中使用這種方式:

ScSetMRStatus((Int32) statusType, ConvertManagedArrayToDelphiDynIntArray(activeMrIds), idDst, ConvertManagedArrayToDelphiDynIntArray(idSrcList), isComplete); 

ConvertManagedArrayToDelpiDynIntArray樣子:

public static IntPtr ConvertManagedArrayToDelphiDynIntArray(int[] array) 
{ 
    if (array == null) return IntPtr.Zero; 

    int elementSize = sizeof(int); 
    int arrayLength = array.Length; 
    int allocatedMemSize = 8 + elementSize * arrayLength; 
    IntPtr delphiArrayPtr = Marshal.AllocHGlobal(allocatedMemSize); 
    Marshal.WriteInt32(delphiArrayPtr, 0, 1); 
    Marshal.WriteInt32(delphiArrayPtr, 4, arrayLength); 
    for (int k = 0; k < arrayLength; k++) { 
     Marshal.WriteInt32(delphiArrayPtr, 8 + k*elementSize, array[k]); 
    } 
    return delphiArrayPtr+8; 
} 

但是,這並不工作!

如何發送c#數組到delphi?

回答

1

它終於工作了!

我們對調用進行了一些更改以釋放分配的內存。

var activeMrIdsNative = ConvertManagedArrayToDelphiDynIntArray(activeMrIds); 
var idSrcListNative = ConvertManagedArrayToDelphiDynIntArray(idSrcList); 
ScSetMRStatus((Int32) statusType, activeMrIdsNative, idDst, idSrcListNative, isComplete); 
Marshal.FreeHGlobal(activeMrIdsNative-8); 
Marshal.FreeHGlobal(idSrcListNative-8); 

我們只是認爲它不會工作,因爲我們沒有看到德爾福方面用它做什麼。所有的數據都進入了delphi dll,它運行良好。

也許存在內存問題,但我們會檢查這一點。