从Delphi调用dotNET并返回一个字符串

Sea*_*kin 11 c# delphi interop

Delphi应用程序如何调用导出的函数(非COM)dotNET程序集并让函数返回一个字符串?

COM不是我的特定应用程序的可能解决方案.我控制了通话的两端.

到目前为止我尝试了什么 - Delphi客户端

type
  TStrProc = procedure( var x: widestring); stdcall;

function TryIt: string;
var
  Handle: THandle;
  Proc: TStrProc;
  InData: widestring;
  OutData: widestring;
begin
  Handle    := LoadLibrary( 'DelphiToDotNet.dll');
  if Handle = 0 then exit;
  @Proc := GetProcAddress( Handle, 'StrProc');
  if @Proc <> nil then
    begin
    InData := 'input';
    Proc( InData);
    OutData := InData;
    end;
  FreeLibrary( Handle);
  result := OutData
end;
Run Code Online (Sandbox Code Playgroud)

dotNET dll方面

public class DotNetDllClass
{
  [DllExport]
  public static string StrProc(ref string s)
  {
      return "Hello from .Net " + s;
  }
}
Run Code Online (Sandbox Code Playgroud)

什么有效

我可以成功地将整数传入和传出dotNET程序.我可以成功地将字符串(Delphi端的宽字符串)传递给dotNET程序.

什么行不通

在上面两个列表中,返回的字符串参数是垃圾.访问它会导致AV.

环境

Delphi XE7,dotNET 4,Win 7,32位应用程序和DLL.

Dav*_*nan 11

与Delphi匹配的C#代码应该是:

[DllExport]
public static void StrProc(
    [MarshalAs(UnmanagedType.BStr)] 
    ref string s
)
{
    s = "Hello from .Net " + s;
}
Run Code Online (Sandbox Code Playgroud)

请注意,返回类型void与您的Delphi代码相匹配.而且我习惯UnmanagedType.BStr了WideString.这是编组文本的最简单方法,因为两个编译器会自动为您执行分配.

不要通过尝试传递一个字符串作为返回值作为一个包装来捕获BStr.Delphi不使用与其他编译器相同的ABI,请参阅为什么不能将WideString用作interop的函数返回值?