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

NoP*_*God 4 c# delphi iis interop

如果我不返回任何内容,则工作正常,或者返回一个整数.但如果我试图返回一个PChar,即...

result := PChar('')  or   result:= PChar('Hello')
Run Code Online (Sandbox Code Playgroud)

网络应用程序只是冻结,我看着它的内存数量在任务管理器中逐渐变得越来越高.

奇怪的是,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();
Run Code Online (Sandbox Code Playgroud)

德尔福:

library TheLib;

function SomeFunction() : PChar export; stdcall;
begin
return PChar('');
end;

exports
    SomeFunction
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

Dampsquid的分析是正确的,所以我不再重复.但是,我更喜欢不同的解决方案,我觉得更优雅.我对这种问题的首选解决方案是使用Delphi Widestring,这是一个BSTR.

在Delphi方面,你这样写:

function SomeFunction: Widestring; stdcall;
begin
  Result := 'Hello';
end;
Run Code Online (Sandbox Code Playgroud)

在C#方面,你这样做:

[DllImport(@"TheLib.dll")]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string SomeFunction();
Run Code Online (Sandbox Code Playgroud)

就是这样.因为双方都使用相同的COM分配器进行内存分配,所以这一切都正常.

更新1

@NoPyGod有趣地指出此代码因运行时错误而失败.看了这个后,我觉得这是Delphi端的一个问题.例如,如果我们按原样保留C#代码并使用以下内容,则会解决错误:

function SomeFunction: PChar; stdcall;
begin
  Result := SysAllocString(WideString('Hello'));
end;
Run Code Online (Sandbox Code Playgroud)

似乎Delphi返回的类型值WideString没有得到应有的处理.Out参数和var参数按预期处理.我不知道为什么返回值会以这种方式失败.

更新2

事实证明,WideString返回值的Delphi ABI 与Microsoft工具不兼容.您不应该使用WideString返回类型,而是通过out参数返回它.有关更多详细信息,请参阅为什么不能将WideString用作互操作的函数返回值?