Самая значительная проблема (есть несколько проблем) заключается в том, что код Delphi работает с массивами символов фиксированной длины, которые нелегко маршалировать.Маршалер C # не имеет типа, который точно соответствует этим вещам.Проблема в том, что массив символов Delphi фиксированной длины не завершается нулем, если он является полной длиной массива.
Другая проблема - это набор символов.Delphi 7 char
- это 8-битный тип ANSI.Вы маршалируете как CharSet.Auto
, который является 16-битным UTF-16 на платформах, отличных от Windows 9x.Я уверен, что вы не работаете в Windows 9x.
Последняя проблема связана с ABI для больших типов, используемых в качестве возвращаемых значений.В Delphi ABI реализованы такие вещи, как дополнительный (скрытый) параметр var
.Таким образом,
function NIRSAPretreatInfor(ModelFileName: TCharStr): TCharStr;
stdCall; external 'modelDLL.dll';
фактически реализован как:
procedure NIRSAPretreatInfor(ModelFileName: TCharStr; var ReturnValue: TCharStr);
stdCall; external 'modelDLL.dll';
Чтобы правильно выполнить маршалинг, вам нужно будет обрабатывать строки вручную.Начнем с некоторых вспомогательных методов:
public const int DelphiTCharStrLength = 600;
public static byte[] NewDelphiTCharStr()
{
return new byte[DelphiTCharStrLength];
}
public static byte[] ToDelphiTCharStr(string value)
{
byte[] result = NewDelphiTCharStr();
byte[] bytes = Encoding.Default.GetBytes(value + '\0');
Buffer.BlockCopy(bytes, 0, result, 0, Math.Min(bytes.Length, DelphiTCharStrLength));
return result;
}
public static string FromDelphiTCharStr(byte[] value)
{
int len = Array.IndexOf(value, (byte)0);
if (len == -1)
len = DelphiTCharStrLength;
return Encoding.Default.GetString(value, 0, len);
}
Они касаются того факта, что массивы символов Delphi фиксированной длины не обязательно должны заканчиваться нулем.
Как только это произойдет, объявление p / invokeэто так:
[DllImport(@"modelDLL.dll", CallingConvention = CallingConvention.StdCall)]
public extern static void NIRSAPretreatInfor(byte[] ModelFileName, byte[] ReturnValue);
Назовите это так:
byte[] outputBytes = NewDelphiTCharStr();
NIRSAPretreatInfor(ToDelphiTCharStr("foo"), outputBytes);
string output = FromDelphiTCharStr(outputBytes);