Delphi (UnicodeString):
function ShowDelphiMsg(inputStr : UnicodeString) : UnicodeString; stdcall;
var a : UnicodeString;
begin
ShowMessage(inputStr);
a := 'Тест!';
result := a;
end;
C#
[DllImport("Native.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
internal static extern string ShowDelphiMsg([MarshalAs(UnmanagedType.LPWStr)] string inputStr);
Такой вариант отлично передает из C# в Delphi строку, Delphi выводит строку. Но основная проблема - ошибка при возврате строки из Delphi.
Впорос: Какой UnmanagedType соответствует UnicodeString из Delphi?
p.s. архитектура у обоих приложений x64
Delphi (WideString):
function ShowDelphiMsg(inputStr : WideString) : WideString; stdcall;
var a : WideString;
begin
ShowMessage(inputStr);
a := 'Тест!';
result := a;
end;
Так же вызывает ошибку при возврате значения.
Упростил функцию
C#:
[DllImport("Native.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BStr)]
internal static extern string ShowDelphiMsg();
Delphi:
function ShowDelphiMsg() : WideString; stdcall;
var a : WideString;
begin
a := 'Тест!';
result := a;
end;
Та же ошибка.
Ответ
Судя по коду UnmanagedType.LPWStr тут используется PWideChar, что есть указатель на WideString. Из функции возвращать надо именно WideString
UPD:
Оказывается, из-за особенностей C# (?) нужно использовать вот такой способ:
Delphi:
function SomeFunction2(out OutVar: Widestring): BOOL; stdcall;
begin
OutVar := 'Hello';
Result := True;
end;
C#
[DllImport(@"Test.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SomeFunction2([MarshalAs(UnmanagedType.BStr)] out string res);
т.е. возвращать WideString через результат нельзя, а вот делать out параметр (но не var см. ответ Alex) - запросто.
Нагуглено: https://stackoverflow.com/questions/9331026/why-can-delphi-dlls-use-widestring-without-using-sharemem
Комментариев нет:
Отправить комментарий