将字符串从delphi dll返回到64位的C#调用者
我有一个C#应用程序,它使用以下代码调用本机Delphi dll:
C# [DllImport("NativeDLL.dll",CharSet = CharSet.Unicode,CallingConvention = CallingConvention.StdCall)] public static extern int GetString(string out str); 德尔福 function GetString(out a: PChar): Integer; stdcall; begin a := PChar('abc'); Result := 1; end; 这在32位应用程序中工作正常.但是当我编译64位的C#exe和Delphi dll时,我遇到了一个奇怪的问题.在Delphi调试器中调用GetString之后,我可以看到.NET代码中某处出现异常,并且Debugger Output窗口中出现以下字符串:“检测到严重错误c0000374”. Google表示此错误与堆损坏有关. BTW.以下组合工作正常: C# [DllImport("NativeDLL.dll",CallingConvention = CallingConvention.StdCall)] public static extern string GetString(string a); 德尔福 function GetString(a: PChar): PChar; stdcall; var inp: string; begin inp := a; Result := PChar('test ' + inp); end; 工作良好.但我确实需要返回一个字符串作为out参数. 解决方法
您不能以这种方式从本机托管传递字符串.你的代码在32位也是错误的,你恰好侥幸逃脱它.代码的第二个版本也是错误的.它似乎只能工作.
你需要: >从共享堆分配,以便托管代码可以从该堆中解除分配. p / invoke的共享堆是COM堆. 选项2总是更可取的.它看起来像这样: [DllImport("NativeDLL.dll",CharSet = CharSet.Unicode)] public static extern int GetString(StringBuilder str,int len); 在原生方面你会有 function GetString(str: PChar; len: Integer): Integer; stdcall; begin StrLCopy(str,'abc',len); Result := 1; // real code would have real error handling end; 然后这样调用: StringBuilder str = new StringBuilder(256); int retval = GetString(str,str.Capacity); 如果您想尝试选项1,它在管理方面看起来像这样: [DllImport("NativeDLL.dll",CharSet = CharSet.Unicode)] public static extern int GetString(out string str); 和这个本地人一样: function GetString(out str: PChar): Integer; stdcall; begin str = CoTaskMemAlloc(SizeOf(Char)*(Length('abc')+1)); StrCopy(str,'abc'); Result := 1; // real code would have real error handling end; 当托管代码将str的内容复制到字符串值时,它会在您返回的指针上调用CoTaskMemFree. 这很容易打电话: string str; int retval = GetString(out str); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |