Я наконец-то придумал решение, которое позволяет избежать всего Alloc / FreeHGlobal, но если это действительно bulletproff по отношению к сборщику мусора, это другое дело.
Решение состоит в том, чтобы сначала очистить структуру TCustomer с помощьюЗатем FillChar копирует данные с помощью процедуры 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 # выглядит примерно так:
[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;
}