c# - 在 IIS 网络服务器上调用 Delphi DLL 的 ASP.NET 网络应用程序在返回 PChar 字符串时锁定

标签 c# delphi iis interop

如果我不返回任何东西,或者我返回一个整数,工作正常。但是如果我尝试返回一个 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/

相关文章:

c# - 遍历二叉树

delphi - Delphi中不同单元中具有相同名称的常量

iis - CPU性能影响GZIP IIS?

c# - 在 VS 开发服务器和 IIS 上为 ASP.NET MVC 应用程序设置文化

c# - 如何在代码中触发点击事件

c# - 如何区分 2 个 DLL 中具有相同名称(和命名空间)的两个类?

c# - 错误处理(发送 ex.Message 给客户端)

delphi - Delphi AV与Try-Except [已关闭]

delphi - 将 Delphi 2009/2010 字符串文字转换为 PAnsiChar

iis - Mercurial/IIS/没有名为 osutil 的模块