ASP.NET web app calling Delphi DLL on IIS webserver, locks up when returning PChar string
c#, delphi, iis, interop
Solution
Dampsquid's analysis is correct so I will not repeat that. However, I prefer a different solution that I feel to be more elegant. My preferred solution for such a problem is to use Delphi `Widestring` which is a `BSTR`.
On the Delphi side you write it like this:
function SomeFunction: Widestring; stdcall;
begin
Result := 'Hello';
end;
And on the C# side you do it like this:
[DllImport(@"TheLib.dll")]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string SomeFunction();
And that's it. Because both parties use the same COM allocator for the memory allocation, it all just works.
Update 1
@NoPyGod interestingly points out that this code fails with a runtime error. Having looked into this I feel it to be a problem at the Delphi end. For example, if we leave the C# code as it is and use the following, then the errors are resolved:
function SomeFunction: PChar; stdcall;
begin
Result := SysAllocString(WideString('Hello'));
end;
It would seem that Delphi return values of type `WideString` are not handled as they should be. Out parameters and var parameters are handled as would be expected. I don't know why return values fail in this way.
Update 2
It turns out that the Delphi ABI for `WideString` return values is not compatible with Microsoft tools. You should not use `WideString` as a return type, instead return it via an `out` parameter. For more details see Why can a WideString not be used as a function return value for interop?
Problem
Works fine if I don't return anything, or I return an integer. But if I try to return a PChar, ie.. ``` result := PChar('') or result:= PChar('Hello') ``` The web app just freezes up and I watch its memory count gradually get higher and higher in task manager. The odd thing is that the DLL works fine on the VStudio debug server, or through a C# app. The only thing I can think of that would make a difference is that the IIS server is running in 64bit Windows. It doesn't appear to be a compatability issue though because I can successfully write to text files and do other things from the DLL... I just can NOT return a PChar string. Tried using PWideChar, tried returning 'something\0', tried everything I could think of. No luck unfortunately. ``` [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 ```