Анализ Dampsquid правильный, поэтому я не буду повторять это. Однако я предпочитаю другое решение, которое я считаю более элегантным. Мое предпочтительное решение для такой проблемы состоит в том, чтобы использовать Delphi Widestring
, который является BSTR
.
На стороне Delphi вы пишете это так:
function SomeFunction: Widestring; stdcall;
begin
Result := 'Hello';
end;
А на стороне C # вы делаете это так:
[DllImport(@"TheLib.dll")]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string SomeFunction();
И это все. Поскольку обе стороны используют один и тот же COM-распределитель для выделения памяти, все это просто работает.
Обновление 1
@ NoPyGod интересно указывает, что этот код завершается с ошибкой во время выполнения. Посмотрев на это, я чувствую, что это проблема в конце Delphi. Например, если мы оставим код C # как есть и будем использовать следующее, ошибки будут устранены:
function SomeFunction: PChar; stdcall;
begin
Result := SysAllocString(WideString('Hello'));
end;
Казалось бы, возвращаемые Delphi значения типа WideString
обрабатываются не так, как должно быть. Выходные параметры и параметры var обрабатываются, как и ожидалось. Я не знаю, почему возвращаемые значения терпят неудачу таким образом.
Обновление 2
Оказывается, что Delphi ABI для WideString
возвращаемых значений несовместим с инструментами Microsoft. Вы не должны использовать WideString
в качестве возвращаемого типа, вместо этого возвращайте его через параметр out
. Подробнее см. Почему WideString не может использоваться как возвращаемое значение функции для взаимодействия?