从 c++ dll 返回 double* 到 delphi 程序

Return double* from c++ dll to delphi program

本文关键字:delphi 程序 double c++ dll 返回      更新时间:2023-10-16

我试图将double数组(声明为double*)返回给delphi程序。在c ++ dll项目中,我有

#define DllExport   __declspec( dllexport )
extern double* array;
extern "C"
{
    DllExport double* SomeMethod(double);
}

卸载 Dll 时array被删除

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.
}

当我在 c++ 控制台应用程序中测试我的 dll 时,我在使用 dll 中的SomeMethod后得到了正确的结果。接下来,我尝试在 Delphi 中测试我的 dll,但方法返回的数组内容是错误的。我使用了以下代码。

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
...

从 c++ dll 返回double*以在 delphi 中使用的正确方法是什么?

附言其他方法以正确的方式工作。例如,dll 返回char*,在德尔福中,我使用 PAnsiChar

更新

下面是编写SomeMethod的文件的一些C++代码。

double* array; // yea it's 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;
}
}

德 尔 福

{$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.

输出

 42666