Вернуть double * из c ++ dll в программу delphi

0

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;
 }
Теги:
dll
pointers
dllexport

1 ответ

1
Лучший ответ

Код в вашем вопросе отлично работает. Это означает, что проблема кроется в другом месте. Здесь доказательство:

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
  • 0
    Спасибо за вашу помощь и терпение. На самом деле проблема была в другой части DLL. Я использовал функцию floor в коде c ++ в некоторой подпрограмме для сравнения двух double значений. По какой-то причине в C ++ и в Delphi это дает разные результаты. Без floor все работает как я хочу.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню