如果我没有返回任何内容,则工作正常,或者返回一个整数。但是,如果我试图返回一个PChar,即..
result := PChar('') or result:= PChar('Hello')
网络应用程序只是冻结,我看着它的内存数量在任务管理器中逐渐变得越来越高。
奇怪的是,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();
的Delphi:
library TheLib;
function SomeFunction() : PChar export; stdcall;
begin
return PChar('');
end;
exports
SomeFunction
答案 0 :(得分:5)
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分配器进行内存分配,所以这一切都可以正常工作。
@NoPyGod有趣地指出此代码因运行时错误而失败。看了这个后,我觉得这是Delphi端的一个问题。例如,如果我们按原样保留C#代码并使用以下内容,则会解决错误:
function SomeFunction: PChar; stdcall;
begin
Result := SysAllocString(WideString('Hello'));
end;
似乎Delphi返回的类型WideString
的值没有得到应有的处理。 Out参数和var参数按预期处理。我不知道为什么返回值会以这种方式失败。
事实证明,WideString
返回值的Delphi ABI与Microsoft工具不兼容。您不应该使用WideString
作为返回类型,而是通过out
参数返回它。有关详细信息,请参阅Why can a WideString not be used as a function return value for interop?
答案 1 :(得分:3)
你不能返回这样的字符串,字符串是函数的本地字符串,一旦函数返回就会被释放,而返回的PChar指向无效的位置。
你需要传入一个指针,在DLL中填充,动态创建字符串并将其释放回c#代码中,或者在你的DLL中创建一个静态缓冲区并返回它。
到目前为止,最安全的方法是将指针传递给函数,即
function SomeFunction( Buffer: PChar; MaxLength: PInteger ): wordbool; stdcall;
{
// fill in the buffer and set MaxLength to length of data
}
在调用dll之前,你应该将MaxLength设置为缓冲区的sixe,以便dll可以检查是否有足够的空间来返回数据。
答案 2 :(得分:-1)
尝试在应用程序池高级设置中启用32位应用程序: