I have a Delphi 2010 DLL that will be used to compress some data from a C# APP. The DLL function looks like this:
function CompressString(aInputString: PAnsiChar; aInputStringSize: Integer;
var aOutPutString: PAnsiChar; var aOutPutStringSize: Integer;
var aErrorMsgBuffer: PAnsiChar; var aErrorMsgBufferSize: integer): Integer;
stdcall; export;
The C# method looks like this:
[DllImport("MyDLL.dll", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi)]
public static extern int CompressString(string aInputString,
int aInputStringSize, ref string aOutPutString,
out int aOutPutStringSize, ref string aErrorMsgBuffer,
out int aErrorMsgBufferSize);
My problem is that aOutPutString is being truncated, only part of the data is being seen by the C# App. If I change aOutPutString inside the Delphi DLL to be a simple literal constant (only for testing) it works fine.
Inside the DLL, I am working with strings. In the end of the function, I call:
StrPCopy(aOutPutString, vOutOutAnsiStr);
To convert an AnsiString do PAnsiChar.
I guess I should not be using PAnsiChar but an array of byte, but I am not sure how to do that.
Using PAnsiChar makes the string truncate at the first ‘0’ byte.
Instead of having an out parameter of the type
PAnsiChar, you can have two out parameters: one of them is a pointer to a byte array, and the other is an integer which will contain the size of the array.You have to be careful not to free the array on the DLL, once you need to access it later. On C# side, in the external function declaration, you’ll catch the pointer as
IntPtrand use theMarshal.Copymethod to copy the content to a C# byte array.