【问题标题】:How to declare array types for unmanaged export如何为非托管导出声明数组类型
【发布时间】:2012-11-30 22:39:11
【问题描述】:

我正在使用UnmanagedExports 从 Delphi Win32 程序中调用 .NET C# 类库函数。像魅力一样工作!

我还没有发现如何在 C# 和 Delphi 端声明数组类型(如 int[] 或 IMyUnknownBasedInterface[]),以便我可以在两种语言之间交换数组。如果不可能,我也很乐意使用某种集合对象或索引器方法。

有什么想法吗?

【问题讨论】:

    标签: c# delphi


    【解决方案1】:

    在 C# 端这样做:

    [DllExport("Foo", CallingConvention = CallingConvention.Stdcall)]
    static extern void Foo(int[] a, int len);
    

    在 Delphi 方面是这样的:

    procedure Foo(a: PInteger; len: Integer); stdcall; external 'manageddll.dll';
    

    要从 Delphi 调用函数,您可以这样做:

    var
      a: array of Integer;
    ....
    SetLength(a, 666);
    //populate a
    Foo(PInteger(a), Length(a));
    

    【讨论】:

    • 酷,谢谢大卫。如果我想传递一个接口数组(IMyUnknownBasedInterface[]),同样适用吗?谢谢!
    • 我相信是的。在 C# 上,IMyUnknownBasedInterface[] 匹配指向数组第一个元素的指针。所以在德尔福方面,你想通过PIMyUnknownBasedInterfacePIMyUnknownBasedInterface = ^IMyUnknownBasedInterface。不确定如何在 C# 端处理引用计数。
    【解决方案2】:

    这在 C# 方面很容易,但在 Delphi 方面它可以是皇家 PITA。

    这里的问题是,如果你有一个从本机编组的接口的数组属性,那么 CLR 将对数组大小非常挑剔。

    你最好的选择是一个安全的数组,它很容易在 C# 中声明...

    public interface ISample
    {
        int[] YourArray
        {
            [return:MarshalAs(UnmanagedType.SafeArray)]
            get;
        }
    

    然而,安全数组在 Delphi 方面处理起来相当麻烦。

    对于我自己的东西,我只是没有在本机和 C# 之间共享的接口中发布数组。 我使用了一个模仿 IEnumerable 的接口,但可以在 Delphi 或 C# 中轻松实现。

    当你让它返回另一个提供方法 MoveNext、GetCurrent 和属性 Current 的接口时,C# 和 Delphi 都会让你愉快地对它进行 foreach。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多