【发布时间】:2012-11-30 22:39:11
【问题描述】:
我正在使用UnmanagedExports 从 Delphi Win32 程序中调用 .NET C# 类库函数。像魅力一样工作!
我还没有发现如何在 C# 和 Delphi 端声明数组类型(如 int[] 或 IMyUnknownBasedInterface[]),以便我可以在两种语言之间交换数组。如果不可能,我也很乐意使用某种集合对象或索引器方法。
有什么想法吗?
【问题讨论】:
我正在使用UnmanagedExports 从 Delphi Win32 程序中调用 .NET C# 类库函数。像魅力一样工作!
我还没有发现如何在 C# 和 Delphi 端声明数组类型(如 int[] 或 IMyUnknownBasedInterface[]),以便我可以在两种语言之间交换数组。如果不可能,我也很乐意使用某种集合对象或索引器方法。
有什么想法吗?
【问题讨论】:
在 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[] 匹配指向数组第一个元素的指针。所以在德尔福方面,你想通过PIMyUnknownBasedInterfacePIMyUnknownBasedInterface = ^IMyUnknownBasedInterface。不确定如何在 C# 端处理引用计数。
这在 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。
【讨论】: