You should export a C function out of your DLL. And decide if you want the DLL function copy data into the passed buffer pointer or just give back the pointer to the data.
I build an example showing the DLL copying the data. I used a dynamic array as you've done in your question. The function inside DLL receive the pointer where to copy data (That is the Delphi dynamic array) and the length of the dynamic array. The function inside the DLL copy some data, up to the maximum length specified, and return the actual length.
I also used Ansi char to pass data as you seems to like this. Could could as well pass Unicode.
DLL source code:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void __stdcall getDataReference(char* data, int* bufferLength)
{
char charArray[] = "Pass this Array of Char By Reference";
if ((data == NULL) || (bufferLength == NULL) || (*bufferLength <= 0))
return;
#pragma warning(suppress : 4996)
strncpy(data, charArray, *bufferLength);
*bufferLength = sizeof(charArray) / sizeof(charArray[0]);
}
And simple console mode Delphi application consuming that DLL:
program CallMyDll;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Winapi.Windows,
System.SysUtils;
type
TGetDataReference = procedure (Data : PAnsiChar;
BufferLength : PInteger); stdcall;
var
DllHandle : THandle;
GetDataReference : TGetDataReference;
procedure callDllFunction();
var
DynamicCharArray : array of AnsiChar;
DataLength : Integer;
S : String;
begin
DataLength := 1000;
SetLength(DynamicCharArray, DataLength);
GetDataReference(PAnsiChar(DynamicCharArray), @DataLength);
SetLength(DynamicCharArray, DataLength);
S := String(PAnsiChar(DynamicCharArray));
WriteLn(S);
end;
begin
try
DllHandle := LoadLibrary('D:\FPiette\Cpp\MyDll\Debug\MyDll.dll');
if DllHandle = 0 then
raise Exception.Create('DLL not found');
@GetDataReference := GetProcAddress(DllHandle, '_getDataReference@8');
if @getDataReference = nil then
raise Exception.Create('getDataReference not found');
callDllFunction();
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
WriteLn('Hit RETURN...');
ReadLn;
end.