Im пытается вернуть массив double
(объявлен как double *) в программу delphi. В проекте c++ dll у меня есть
#define DllExport __declspec( dllexport )
extern double* array;
extern "C"
{
DllExport double* SomeMethod(double);
}
и array
удалился при выгрузке Dll
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch( ul_reason_for_call )
{
...
case DLL_PROCESS_DETACH:
delete [] array;
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
Пока я тестировал свою DLL в консольном приложении c++, я получил правильный результат после использования SomeMethod
из dll. Затем я попытался проверить свою DLL в Delphi, но содержимое массива, возвращаемого методом, неверно. Я использовал следующий код.
TSomeMethod = function(level : Double): PDouble; cdecl;
...
var
SomeMethod: TSomeMethod;
arr: PDouble;
...
if Assigned(SomeMethod) then
begin
arr:= SomeMethod(15);
writeln(arr^:2:0);
inc(arr);
writeln(arr^:2:0);
end
...
Каков правильный способ возврата double*
из c++ dll для использования в delphi?
PS Другие методы работают правильно. Например, dll возвращает char*
а в delphi я получил его с помощью PAnsiChar
ОБНОВИТЬ
Вот несколько c++ кода из файла, где написан SomeMethod
.
double* array; // yea it an array that declared as external in other file;
...
double* SomeMethod(double level)
{
...
deque<double> arrayToReturn;
... // some actions with deque
array= new double[arrayToReturn.size()];
for (unsigned int i = 0; i<arrayToReturn.size(); i++)
array[i] = arrayToReturn[i];
return array;
}
Код в вашем вопросе отлично работает. Это означает, что проблема кроется в другом месте. Здесь доказательство:
C++
#include <Windows.h>
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) double* SomeMethod(double)
{
double* array = new double[2];
array[0] = 42;
array[1] = 666;
return array;
}
}
Delphi
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
type
TSomeMethod = function(level : Double): PDouble; cdecl;
var
SomeMethod: TSomeMethod;
arr: PDouble;
lib: HMODULE;
begin
lib := LoadLibrary('MyDll.dll');
Win32Check(lib<>0);
SomeMethod := GetProcAddress(lib, 'SomeMethod');
Win32Check(Assigned(SomeMethod));
arr:= SomeMethod(15);
Writeln(arr^:3:0);
inc(arr);
Writeln(arr^:3:0);
Readln;
end.
Вывод
42 666
floor
в коде c ++ в некоторой подпрограмме для сравнения двухdouble
значений. По какой-то причине в C ++ и в Delphi это дает разные результаты. Безfloor
все работает как я хочу.