如何将c#中的int数组编组为delphi

时间:2017-09-22 09:27:22

标签: c# delphi interop pinvoke

我从Delphi2006制作的dll中进行了以下导出。

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 个答案:

答案 0 :(得分: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方面对它做了什么。所有数据都可以进入delphi dll并且运行良好。

可能存在内存问题,但我们会对此进行检查。