Delphi XE DLL在c#中.带WideString的编组结构

本文关键字:WideString 结构 XE DLL Delphi | 更新日期: 2023-09-27 18:13:06

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中Name and Caption是一个数组[1..]50]的Char和我使用[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]它的工作,但最多256个字符是非常少的和名称,标题与西里尔字符是空的。

Delphi XE DLL在c#中.带WideString的编组结构

你的代码工作完美,当我运行它。我希望您的实际代码与问题中的代码在某些方面有所不同。使用问题中的代码,字符串值将返回到您的c#程序中。

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

  1. CharSet.Unicode在这里不起作用。BStr总是UTF-16编码。
  2. 使用packed是低效的。我建议你删除它。
  3. 该参数应该是真正的out参数。