在Delphi中我有这样的结构:
TCustomerInfo = Packed Record
CustomerNo: Integer;
FirstName: String[50];
LastName: String[50];
End;
使用这样的虚拟过程:
procedure GetCustomer(CustomerNo: Integer; var CustomerInfo: TCustomerInfo);
begin
CustomerInfo.CustomerNo := 19901;
CustomerInfo.FirstName := 'JOHN';
CustomerInfo.LastName := 'DOE';
end;
在C#中我有这个:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
struct CUSTOMER_INFO
{
public Int32 CustomerNo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=50)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=50)]
public string LastName;
}
使用这样的导入Delphi函数:
[DllImport("Exceline.dll")]
extern static void GetCustomer(Int32 CustomerNo, ref CUSTOMER_INFO CustomerInfo);
我们的想法是确保C#应用程序正在处理所有内存分配和存储。
我的问题是从GetCustomer返回后没有任何内容被分配给我的C#结构: - /
答案 0 :(得分:2)
我终于提出了一个避免所有Alloc / FreeHGlobal的解决方案,但如果这对于垃圾收集器来说真的是关于另一件事的话。
解决方案是先用FillChar清除TCustomer结构,然后使用Move程序复制数据。
delphi记录如下所示:
TCustomer = packed record
CustomerNo: Integer;
FirstName: array [1..50] of Char;
LastName: array [1..50] of Char;
end;
然后我用一个过程将字符串复制到结构中:
procedure StrToBuf(Str: String; var buf);
begin
Move(Pointer(str)^, buf, Length(str));
end;
在一个或多或少像这样的过程中:
procedure LoadCustomerFromQuery(var Query: TQuery; var Customer: TCustomer); stdcall;
begin
FillChar(Customer, SizeOf(Customer), 0);
StrToBuf(Query.FieldByName('FNAVN').AsString, Customer.FirstName);
StrToBuf(Query.FieldByName('ENAVN').AsString, Customer.LastName);
Customer.CustomerNo := Query.FieldByName('KUNDENR').AsInteger;
end;
最后,C#struct看起来像这样:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
public struct TCustomer
{
public Int32 CustomerNo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string LastName;
}
答案 1 :(得分:1)
extern static void GetCustomer(Int32 CustomerNo, IntPtr CustomerInfo);
...
var info = default(CUSTOMER_INFO);
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(info));
Marshal.StructureToPtr(info, ptr, false);
GetCustomer(n, ptr);
Marshal.PtrToStructure(ptr, info);
Marshal.FreeHGlobal(ptr);