如果我不返回任何东西,或者我返回一个整数,工作正常。但是如果我尝试返回一个 PChar,即..
result := PChar('') or result:= PChar('Hello')
Web 应用程序只是卡住,我看到它的内存计数在任务管理器中逐渐变得越来越高。
奇怪的是,DLL 在 VStudio 调试服务器上或通过 C# 应用程序运行良好。我能想到的唯一会有所不同的是 IIS 服务器在 64 位 Windows 中运行。
这似乎不是兼容性问题,因为我可以成功地写入文本文件并从 DLL 中执行其他操作...我只是无法返回 PChar 字符串。
尝试使用 PWideChar,尝试返回“something\0”,尝试了我能想到的所有方法。不幸的是没有运气。
[DllImport("TheLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern string SomeFunction();
string result = SomeFunction();
德尔福:
library TheLib;
function SomeFunction() : PChar export; stdcall;
begin
return PChar('');
end;
exports
SomeFunction
最佳答案
Dampsquid's analysis是正确的,所以我不会重复。但是,我更喜欢另一种我觉得更优雅的解决方案。对于此类问题,我的首选解决方案是使用 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;
WideString
类型的 Delphi 返回值似乎没有按应有的方式处理。 Out 参数和 var 参数按预期处理。我不知道为什么返回值会以这种方式失败。
更新2
事实证明,WideString
返回值的 Delphi ABI 与 Microsoft 工具不兼容。您不应使用 WideString
作为返回类型,而应通过 out
参数返回它。有关详细信息,请参阅 Why can a WideString not be used as a function return value for interop?
关于c# - 在 IIS 网络服务器上调用 Delphi DLL 的 ASP.NET 网络应用程序在返回 PChar 字符串时锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9322938/