2013-10-23 1 views
0

double (double *로 선언 된) 배열을 델파이 프로그램에 반환하려고합니다. C++ DLL 프로젝트에서 내가 C++ 콘솔 응용 프로그램에서 내 DLL을 테스트하는 동안 DLL이 내가 DLL에서 SomeMethod를 사용 후 바로 결과를 얻었다 C++ DLL에서 delphi 프로그램으로 double *을 반환하십시오.

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

을 언로드 될 때

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

array가 삭제 가지고있다. 다음으로 델파이에서 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 
... 

델파이에서 사용하는 double* C에서 ++ DLL을 반환하는 적절한 방법은 무엇입니까?

P. 다른 방법은 올바른 방식으로 작동합니다. 예를 들어 DLL은 char*를 반환하고 델파이에서 나는 PAnsiChar

UPDATE 여기

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; 
} 
+0

는 것으로 someMethod에 대한 코드가 있습니까() : 여기 증거가있어? SomeMethod()가 메소드의 모든 지역 변수를 반환하면 SomeMethod()의 지역 변수에 값을 저장하면 반환 될 때 사라집니다. 그러면 메소드가 왜 쓰레기를 반환하는지 설명 할 수 있습니다. – rhody

+0

SomeMethod()에 대해 어떤 호출 규칙을 사용하고 있는지 확인해야 할 또 다른 사항은 cdecl입니까? 귀하의 델파이 호출이 그렇게 선언 된 이후이어야합니다. – rhody

+0

배열이 왜 extern입니까? 정의 선언은 어디에 있습니까? 완전한 코드를 표시하십시오. –

답변

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

} 

델파이

{$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의 다른 부분에있었습니다. 두 개의 'double'값을 비교하기 위해 일부 루틴에서 C++ 코드의 'floor'함수를 사용했습니다. 어떤 이유에서 C++과 델파이에서는 다른 결과를 보여줍니다. 'floor' 없이는 모든 것이 제대로 작동합니다. – Mitya

관련 문제