Можно ли вернуть 2 одномерных массива из dll
//+------------------------------------------------------------------+
//| fft test.mq4 |
//+------------------------------------------------------------------+
#import "fftlib.dll"
void FFTR(double A[], int N, double FA[], double FB[]);
#import
double buf[1];
double fa[1];
double fb[1];
int n = 10;
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int len = MathPow(2,n);
ArrayResize(buf,len);
ArrayResize(fa,len);
ArrayResize(fb,len);
//----
int i;
for(i=0;i<len;i++) buf[i]= Close[i];
FFTR(buf, len, fa, fb);
//Alert(len);
Alert("Скрипт закончил свою работу");
//----
return(0);
}
//+------------------------------------------------------------------+
Главный модуль dll
unit MainUnit;
interface
uses
xxxxxxxxxxxxx;
procedure DLLFinalization;
procedure DLLInitialization;
procedure StartSynchronisation;
procedure StopSynchronisation;
procedure FFTR(const A: TRealArray; const N:Integer; out FA, FB:
TRealArray); stdcall;
procedure iFFTR(const FA, FB: TRealArray; const N: Integer; out A:
TRealArray); stdcall;
exports
FFTR, iFFTR;
var
hMutex1: THandle = 0;
hMutex2: THandle = 0;
hMutex3: THandle = 0;
hMutex4: THandle = 0;
implementation
procedure DLLFinalization;
begin
//
end;
procedure DLLInitialization;
begin
//
end;
procedure StartSynchronisation;
begin
hMutex1:= CreateMutex(nil, False, '');
hMutex2:= CreateMutex(nil, False, '');
hMutex3:= CreateMutex(nil, False, '');
hMutex4:= CreateMutex(nil, False, '');
end;
procedure StopSynchronisation;
begin
CloseHandle(hMutex1);
CloseHandle(hMutex2);
CloseHandle(hMutex3);
CloseHandle(hMutex4);
end;
procedure FFTR(const A: TRealArray; const N: Integer; out FA, FB:
TRealArray);
var
F: TComplexArray;
I: Integer;
begin
SetLength(FA,N);
SetLength(FB,N);
if WaitForSingleObject(hMutex3, INFINITE) = WAIT_OBJECT_0 then
try
FFT(A, N, F);
for I := 0 to High(A) do
begin
FA[I]:= F[I].X;
FB[I]:= F[I].Y;
end;
except
end;
Sleep(15);
ReleaseMutex(hMutex3);
end;
procedure iFFTR(const FA, FB: TRealArray; const N: Integer; out A:
TRealArray);
var
F: TComplexArray;
I: Integer;
begin
if WaitForSingleObject(hMutex4, INFINITE) = WAIT_OBJECT_0 then
try
for I := 0 to High(FA) do
begin
F[I].X:= FA[I];
F[I].Y:= FB[I];
end;
iFFT(F, N, A);
except
end;
Sleep(15);
ReleaseMutex(hMutex4);
end;
end.
PS: в тестовом приложении все отрабатывает корректно
Массивы по ссылке передавать надо.
вызывающий скрипт:
//+------------------------------------------------------------------+
//| fft test.mq4 |
//+------------------------------------------------------------------+
#import "fftlib.dll"
void FFTR(double A[], int N, double &FA[], double &FB[]);
#import
double buf[1];
double fa[1];
double fb[1];
int n = 10;
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int len = MathPow(2,n);
ArrayResize(buf,len);
ArrayResize(fa,len);
ArrayResize(fb,len);
//----
int i;
for(i=0;i<len;i++) buf[i]= Close[i];
FFTR(buf, len, fa, fb);
//Alert(len);
Alert("Скрипт закончил свою работу");
//----
return(0);
}
//+------------------------------------------------------------------+
Как здесь быть? Пока не знаю. Есть мысли?
А как же. Переделать все передаваемые массивы на указатели. Принимать указатели. Работать с указателем. Убрать изменение размеров.
Просчет преобразования Фурье штука медленная, так что спокойно без потери производительности можно завести два локальных массива типа array of double.
Перед преобразованием скопировать данные туда, а после преобразования оттуда.
Кодом, извините, помогу вряд ли. На Delphi последний раз писал лет 5 назад, так что читать код могу, писать вслепую никак, только тезисно.
Соглашение о вызовах учел (stdcall).
При запуске тестового скрипта терминал просто замерзает и все.
Заранее благодарен.