I’ve been trying to invoke a method that have been created in Delphi in the following way:
function _Func1(arrParams: array of TParams): Integer;stdcall;
type
TParams = record
Type: int;
Name: string;
Amount : Real;
end;
My code is:
[DllImport("some.dll", EntryPoint = "_Func1", CallingConvention = CallingConvention.StdCall)]
public static extern int Func(
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)] TParams[] arrParams)
And the struct is:
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TParams
{
public int Type;
[MarshalAs(UnmanagedType.AnsiBStr)]
public string Name;
public double Amount;
}
When I am calling this method I’m getting the error:
Cannot marshal field ‘Name’ of type ‘TParams’: Invalid managed/unmanaged type combination (String fields must be paired with LPStr, LPWStr, BStr or ByValTStr).
However none of those combinations works, as Delphi’s strings are prefixed with its length and it is Ansi for sure (I’ve tried it with other string parameters). Does anyone have a clue how to solve this?
There are two main problems with this, use of open arrays and use of Delphi
string.Open arrays
Delphi open arrays are implemented by passing a pointer to the first element of the array and an extra parameter specifying the index of the last item,
highin Delphi terminology. For more information see this answer.Delphi strings
The C# marshaller cannot interop with a Delphi string. Delphi strings are private types, only to be used internally to a Delphi module. Instead you should use a null-terminated string,
PAnsiChar.Putting it all together you can write it like this:
Delphi
C#