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/

相关文章:

delphi - 为什么在 Delphi 2010 中将 SSl 添加到 Indy 邮政编码查找示例时得到 "wrong version error"?

windows - 密码保护 IIS 目录

asp.net - 无法从 VS2015 运行 IIS Express

asp.net - 两个应用程序如何使用单个 ASPState 数据库

c# - 如何实例化嵌套 IList<T> 的 IList<T>?

c++ - 找到控件相对于其父窗口的位置的最佳方法是什么?

delphi - DBGrid组件如何确定要显示的初始列宽?

C# Visual Studio 以另一种方式打开上下文菜单?

c# - 如何安装/部署在 C#.net 中开发的 VSTO Excel 2010 插件?

c# - 在 dataGridView 中的单个列下显示不同表中的两个属性