I've tried several variations of the code below with returning HRESULT (which is the preferable COM standard) or returning BSTR. I've tried other datatypes as well. I usually get a "missing implementation of interface method" compile error, but when I used a return type of WideString, there was a runtime AccessViolationException on the result:=RetVal;
instruction.
I'm using C# on the client side:
var msg = delphi.GetMessage("My Message");
Here is mi RIDL:
HRESULT _stdcall GetMessage([in] BSTR msg, [out, retval] BSTR* RetVal);
Here is my implementation:
function TDelphiCom.GetMessage(msg:WideString; out RetVal:WideString):HRESULT;
var
tempString: string;
begin
tempString:=msg;
RetVal:=WideString(tempString);
end;
What is the correct way to pass strings in/out of a Delphi COM server?
Your RIDL declaration is correct.
You did not show the C# declaration of the method, so we can't see if you are marshaling parameters correctly or not.
On the Delphi side, your implementation is missing the stdcall
calling convention (to match the RIDL declaration), as well as exception handling so you can return a proper HRESULT
on failures:
function TDelphiCom.GetMessage(msg: WideString; out RetVal: WideString): HRESULT; stdcall;
var
tempString: string;
begin
try
tempString := string(msg);
RetVal := WideString(tempString);
Result := S_OK;
except
// do something...
Result := DISP_E_EXCEPTION;
end;
end;
Though, you really should use the safecall
calling convention instead and let it deal with the error handling for you:
function TDelphiCom.GetMessage(msg: WideString): WideString; safecall;
var
tempString: string;
begin
tempString := string(msg);
Result := WideString(tempString);
end;