C#中的Delphi XE DLL。使用WideString编组结构

时间:2014-07-15 14:04:52

标签: c# delphi pinvoke

我的Delphi dll中的代码:

...

type
  TPrototype = packed record
    TypeControl: Integer;
    Left: Integer;
    Top: Integer;
    Width: Integer;
    Height: Integer;
    Name: WideString;
    Caption: WideString;
  end;

...

procedure AssignPrototype(var Prototype: TPrototype); stdcall;
begin

  FillChar(Prototype, SizeOf(Prototype), 0);

  with Prototype do begin
    TypeControl := 1;
    Left   := 10;
    Top    := 20;
    Height := 30;
    Width  := 30;
    Caption := 'mycaption';
    Name := 'myname'
  end;
end;

...

exports
 AssignPrototype;

begin
end.

C#中的代码:

...
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=1)]
        public struct Prototype
        {
                public Int32 TypeControl;
                public Int32 Left;
                public Int32 Top;
                public Int32 Width;
                public Int32 Height;
                [MarshalAs(UnmanagedType.BStr)]
                public string Name;
                [MarshalAs(UnmanagedType.BStr)]
                public string Caption;
        }
...
[DllImport("DLL.dll", CallingConvention=CallingConvention.StdCall]
public static extern void AssignPrototype(ref Prototype prototype);
...

但它不起作用。如果在Delphi 7中名称和标题是Char的数组[1..50]并且我使用[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]它可以工作,但最多256个字符非常少而名称,带有西里尔字符的标题是空值。

1 个答案:

答案 0 :(得分:2)

您的代码完全像我运行时一样。我希望您的实际代码在某种程度上与问题中的代码有所不同。使用问题中的代码,字符串值将返回到C#程序中。

我有一些意见和改进建议:

  1. CharSet.Unicode在这里没有用处。 BStr始终为UTF-16编码。
  2. packed的使用效率低下。我建议你删除它。
  3. 参数应该是out参数。