如果我不返回任何东西,或者我返回一个整数,就可以正常工作。但是如果我尝试返回一个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();delphi:
library TheLib;
function SomeFunction() : PChar export; stdcall;
begin
return PChar('');
end;
exports
SomeFunction发布于 2012-02-17 20:34:22
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
@NoPy神有趣地指出,这段代码会因为运行时错误而失败。在研究过这个问题之后,我觉得这是Delphi端的一个问题。例如,如果我们保持C#代码不变,并使用以下代码,那么错误就会得到解决:
function SomeFunction: PChar; stdcall;
begin
Result := SysAllocString(WideString('Hello'));
end;似乎WideString类型的Delphi返回值没有得到应有的处理。Out参数和var参数按照预期进行处理。我不知道为什么返回值会以这种方式失败。
更新2
事实证明,Delphi ABI for WideString返回值与微软工具不兼容。您不应使用WideString作为返回类型,而应通过out参数返回它。有关更多详细信息,请参阅Why can a WideString not be used as a function return value for interop?
发布于 2012-02-17 17:51:58
您不能返回这样的字符串,该字符串是函数的本地字符串,一旦函数返回,它就会被释放,从而使返回的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设置为缓冲区的六位数,以便dll可以检查是否有足够的空间可供返回数据。
发布于 2012-02-17 17:06:48
尝试在应用程序池高级设置中启用32位应用程序:

https://stackoverflow.com/questions/9322938
复制相似问题