How does a Delphi application call an exported function (non-COM) dotNET assembly and have the function return a string?
COM is not a possible solution for my particular application. I have control over both ends of the call.
type
TStrProc = procedure( var x: widestring); stdcall;
function TryIt: string;
var
Handle: THandle;
Proc: TStrProc;
InData: widestring;
OutData: widestring;
begin
Handle := LoadLibrary( 'DelphiToDotNet.dll');
if Handle = 0 then exit;
@Proc := GetProcAddress( Handle, 'StrProc');
if @Proc <> nil then
begin
InData := 'input';
Proc( InData);
OutData := InData;
end;
FreeLibrary( Handle);
result := OutData
end;
public class DotNetDllClass
{
[DllExport]
public static string StrProc(ref string s)
{
return "Hello from .Net " + s;
}
}
I can successfully pass integers into and out of dotNET procedures. I can successfully pass strings (widestring on the Delphi side) into dotNET procedures.
In the above two listings, the string parameter returned is junk. Accessing it causes an AV.
Delphi XE7, dotNET 4, Win 7, 32 bit application and dll.
The C# code to match the Delphi should be:
[DllExport]
public static void StrProc(
[MarshalAs(UnmanagedType.BStr)]
ref string s
)
{
s = "Hello from .Net " + s;
}
Note that the return type is void
to match your Delphi code. And I've used UnmanagedType.BStr
to match WideString
. That's the simplest way to marshal text since the allocation is performed automatically for you by the two compilers.
Don't get caught out by trying to pass a string as a return value marshaled as a BStr
. Delphi doesn't use the same ABI as other compilers, see Why can a WideString not be used as a function return value for interop?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With