The function that these developers have supplied cannot be called reliably. And it certainly cannot be called from C# using the code you have been supplied. The function you have been supplied has been declared like this:
function EncryptPassword(inputString: PWideChar;
var outputString: PWideChar): WordBool; stdcall;
The return value really should be LongBool
, but that won't actually matter.
The main problem is the second parameter. This requires the Delphi code to allocate a string, and return the pointer to that string in outputString
. The calling code has no way to deallocate that string. C# code that could call the function looks like this:
[DllImport("PasswordEncrypt.dll", CharSet = CharSet.Unicode)]
private static extern bool EncryptPassword(string inputString,
out IntPtr outputString);
You would call it like this:
IntPtr outputStringPtr;
if (!EncryptPassword(inputString, out outputStringPtr))
// handle error
string outputString = Marshal.PtrToStringUni(outputStringPtr);
And this leaves the memory that outputStringPtr
still allocated with no way for you to deallocate it.
Of course, even this assumes that the Delphi developer allocated the memory in such a way that it would outlast the call to EncryptPassword
. Quite possibly they implemented EncryptPassword
like this:
function EncryptPassword(inputString: PWideChar;
var outputString: PWideChar): WordBool; stdcall;
var
output: UnicodeString;
begin
output := InternalEncryptPassword(string(intputString));
outputString := PWideChar(output);
Result := True;
end;
This function deallocates the memory that outputString
points to as soon as it returns.
So, the bottom line is that the code you have been supplied with is no good. Here is what it should look like:
function EncryptPassword(inputString: WideString;
out outputString: WideString): LongBool; stdcall;
That function might be implemented something like this:
function EncryptPassword(inputString: WideString;
out outputString: WideString): LongBool; stdcall;
begin
outputString := InternalEncryptPassword(intputString);
Result := True;
end;
On the C# side it looks like this:
[DllImport("PasswordEncrypt.dll", CharSet = CharSet.Unicode)]
private static extern bool EncryptPassword(
[MarshalAs(UnmanagedType.BStr)]
string inputString,
[MarshalAs(UnmanagedType.BStr)]
out string outputString
);
And call it like this:
string outputString;
if (!EncryptPassword(inputString, out outputString))
// handle error