Reputation: 2116
I am calling a delphi function within a dll from c#. Here is the delphi function signature -
function CALinkDecode(sCode: PWideChar; SubscriberID, MailshotID, LinkID: PDWORD):
PAnsiChar; stdcall;
And here is how i am calling it.
string input = "qvoxyetvr7wksss2zbrmr";
int cas, cam, cal;
var errorString = CALinkDecode(input, out cas,
out cam, out cal);
But when i run the app its evaluating this condition as true in delphi function -
if (sCode = nil) or (Length(sCode) <> 21) or (SubscriberID = nil) or (MailshotID = nil) or (LinkID = nil) then
begin
Result := 'E_INVALIDARG';
end
I would just like to know if i am passing in the correct datatypes for the function signature and what is the correct way to do it. Thanks.
Upvotes: 3
Views: 779
Reputation: 612794
Your immediate problem is likely that you are passing ANSI text to the sCode parameter. Unfortunately you omitted your p/invoke declaration which would have made that clear.
That's easy to fix, but you have much bigger problems. This function is hard to call because it has been designed incorrectly. It's only viable if it returns constant strings that are allocated by the compiler rather than heap allocated strings. You could force it to work with that signature if you:
It looks like you are returning COM error codes in string form. That's perverse. Instead you could make your life very easy by returning HRESULT.
Anyway, to answer the direct question you declare the p/invoke like this:
[DllImport(@"Mylib.dll", CharSet=CharSet.Unicode)]
static extern IntPtr CALinkDecode(
string sCode,
out uint SubscriberID,
out uint MailshotID,
out uint LinkID
);
Then call like this
IntPtr retvalptr = CALinkDecode(...);
Then marshal the pointer to a string
string retval = Marshal.PtrToStringAnsi(retvalptr);
But remember that this can only work if the returned string data is statically allocated. Otherwise you will have leaks, or access violations.
My primary advice is to redesign the interface. Don't return an error code in a string.
On a general note, if you must pass strings from Delphi to C# do it like this:
Note that you cannot marshal a WideString return value to MS tools because Delphi uses a different ABI for return values. That's why you use an out parameter.
Upvotes: 4