将字符串从Delphi dll传递到.net

将字符串从Delphi dll传递到.net,.net,vb.net,delphi,pinvoke,.net,Vb.net,Delphi,Pinvoke,关于这个问题,我搜索了很多,但对于如何将字符串从delphi dll传递到.NET并没有明确的答案 下一个代码基于msdn帮助文件: //Delphi代码 函数myDelphiFunc(变量缓冲区:PChar):整数;出口;stdcall; 缓冲区:='这是一个测试'; 返回值:=0; 结束; //vb.NET代码 _ 作为整数的公共函数myDelphiFunc(ByVal缓冲区作为字符串) 公共子myNETFunc() Dim缓冲区大小为整数=25 Dim buffer As String=新

关于这个问题,我搜索了很多,但对于如何将字符串从delphi dll传递到.NET并没有明确的答案 下一个代码基于msdn帮助文件:

//Delphi代码
函数myDelphiFunc(变量缓冲区:PChar):整数;出口;stdcall;
缓冲区:='这是一个测试';
返回值:=0;
结束;
//vb.NET代码
_
作为整数的公共函数myDelphiFunc(ByVal缓冲区作为字符串)
公共子myNETFunc()
Dim缓冲区大小为整数=25
Dim buffer As String=新字符串(CChar(“”),缓冲区大小)
调用myDelphiFunc(缓冲区)
MsgBox(Strings.Left(buffer,InStr(buffer,Chr(0))-1))
端接头
调用myDelphiFunc时,我在“buffer”变量中收到一个空字符串。我做错了什么


提前感谢

您的代码应替换为

function myDelphiFunc(var Buffer: PChar): Integer; export; stdcall;
const
  tmp = 'this is a test';
begin
  Buffer := StrAlloc(Lenght(tmp)+1);
  StrPCopy(Buffer, PChar(tmp));
  Return:=0;
end;

你的代码有很多错误。主要故障有:

  • Delphi函数通过引用接收指针,但VB代码通过值传递指针
  • Delphi代码需要将字符串复制到提供的缓冲区中
  • Delphi代码应该使用PAnsiChar来匹配VB。或者p/invoke上的PWideChar和CharSet.Unicode
  • VB代码需要使用StringBuilder而不是String,以便将字符串封送回调用方
  • 该函数需要接受一个长度参数,以避免缓冲区溢出
然而,我不确定是否值得尝试深入理解它。最简单的方法是使用在共享COM堆上分配的BSTR。这使函数更易于使用,并隐藏了所有内存分配的复杂性

Delphi

procedure TestFunc(out str: WideString); stdcall;
begin
  str := 'foo';
end;
VB

<DllImport(path)> _ 
Public Sub TestFunc(<MarshalAs(UnmanagedType.BStr)> ByRef str As String)
\u
公共子TestFunc(ByRef str作为字符串)

没有。那不行。需要删除Delphi中的var。需要使用PAnsiChar。需要在.net端使用StringBuilder。在Delphi端,您需要复制到提供的缓冲区中。Delphi方面不需要使用导出。@DavidHeffernan为什么在CLR基于UTF-16时使用AnsiChar?如果使用P*Char,CLR应该如何传递到Delphi缓冲区len?@arich P/invoke的默认封送是ANSI。UTF16使用CharSet.Unicode。缓冲区长度需要一个额外的参数。例如,根据GetWindowText。请在pinvoke.net上查找。谢谢AlexSC,最后我使用了David Hofferman的解决方案。奇怪的是,对于试图返回的字符串,您有一个var参数。我对VB一无所知,但在我看来,您已经分配了缓冲区,因此无需从Delphi DLL返回新的字符指针。但是,我决定不质疑您的设计,并发布了一个与您当前的Delphi代码兼容的答案。+1更好,如果您的.NET应用程序需要大量与dll交互,请将dll实现为com服务器,并利用Delphi和.NET提供的广泛互操作支持。这是一个非常好的信息。我有一套Delphi代码,我想将其提供给.NET。有什么要先读的提示吗?+1谢谢David Heffernan。我的应用程序现在运行良好。我希望这段简单的代码可以帮助其他程序员。@Leonardoherra您可以开始使用Delphi和.NET。
<DllImport(path)> _ 
Public Sub TestFunc(<MarshalAs(UnmanagedType.BStr)> ByRef str As String)