Given the code you have shown, the only way to do what you want (without changing the DLL function's signature) is if the DLL function returns the required buffer length if the input buffer is too small, eg:
extern "C" __declspec(dllexport) int sendUserAllocatedArray(char* data, int length);
int sendUserAllocatedArray(char* data, int length)
{
char char_array[] = "this array length is more than 10";
int datLength = sizeof(char_array);
if ((data) && (datLength <= length))
memcpy(data, char_array, length);
return datLength;
}
Then the Delphi code can do this:
function sendUserAllocatedArray(AllocatedArrayPtr: PAnsiChar; Length: Integer): Integer; cdecl; external 'DLLlibrary.dll';
var
myCharPtr : array of AnsiChar;
size : integer;
UserAllocatedArray: array[0..10] of AnsiChar;
arrayPtr: PAnsiChar;
begin
UserAllocatedArray := 'test123';
size := sendUserAllocatedArray(UserAllocatedArray, Length(UserAllocatedArray));
if size <= Length(UserAllocatedArray) then
begin
arrayPtr := UserAllocatedArray;
end else
begin
SetLength(myCharPtr, size);
arrayPtr := PAnsiChar(myCharPtr);
StrLCopy(arrayPtr, UserAllocatedArray, size-1);
size := sendUserAllocatedArray(arrayPtr, size);
end;
// use arrayPtr up to size chars as needed...
end;
Which can be simplified to this:
function sendUserAllocatedArray(AllocatedArrayPtr: PAnsiChar; Length: Integer): Integer; cdecl; external 'DLLlibrary.dll';
var
size : integer;
UserAllocatedArray: array of AnsiChar;
begin
SetLength(UserAllocatedArray, 10);
StrLCopy(PAnsiChar(UserAllocatedArray), 'test123', Length(UserAllocatedArray)-1);
repeat
size := sendUserAllocatedArray(PAnsiChar(UserAllocatedArray), Length(UserAllocatedArray));
if size <= Length(UserAllocatedArray) then Break;
SetLength(UserAllocatedArray, size);
until False;
// use UserAllocatedArray up to size chars as needed...
end;
Or this:
function sendUserAllocatedArray(AllocatedArrayPtr: PAnsiChar; Length: Integer): Integer; cdecl; external 'DLLlibrary.dll';
var
size : integer;
UserAllocatedArray: array of AnsiChar;
begin
size := sendUserAllocatedArray(nil, 0);
SetLength(UserAllocatedArray, size);
StrLCopy(PAnsiChar(UserAllocatedArray), 'test123', size-1);
size := sendUserAllocatedArray(PAnsiChar(UserAllocatedArray), size);
// use UserAllocatedArray up to size chars as needed...
end;
databeingnull.lengthshould then pass as a pointer instead of by value andsendUserAllocatedArrayshould populate it with the length of buffer it will require. The caller can then allocate an appropriate buffer and callsendUserAllocatedArrayagain, this time with a valid buffer passed indata.....section. But since the function already outputs the copiedlengthas a return value, it is possible for it to return the requiredlengthwithout changing that parameter to a pointer. The caller can simply compare the returnedlengthwith the inputlength, and if the returnedlengthis larger than retry with a larger buffer. Some Win32 APIs work this way.