Help solve a problem with importing a function from a dll - page 3

 

Don't thank :-). You will do everything yourself :-).

Spelled out step by step:

.

#1 (test one, you don't have to do it ;-) :

In C++, create a matrix with number of rows MAX_ROW = 5...10, columns MAX_COL = 5...10 (numbers randomly).

Make randomly filled with data.

.

#2 (test one, you don't have to do ;-) : solve the following problem:

The matrix from step #1 needs to be represented in one-dimensional form.

create one-dimensional array double of size=MAX_ROW*MAX_COL, where data is stored according to the formula

for(line = 0 ... MAX_COL-1)

for(column = 0 ... MAX_COL-1)

array[line*MAX_COL + column] = data[line][column];

.

#3: solve the following problem / as a function

You are given a one-dimensional array double from step (2), the number of rows and columns.

You must put the data from this array into an ap::real_2d_array object

.

#4: You get the ap::real_2d_array / object as a function

You have to convert it to a one-dimensional array double, get the number of rows and columns.

.

#5 (test one, you don't have to do ;-) :

You have to convert the one-dimensional array to a two-dimensional matrix (as in step 1).

Compare the resulting matrix with the original matrix from step 1.

In case of mismatch, figure it out.

.

The main functions that will be needed are functions 3 and 4.

Steps 1,2 = training, you will have to pack the data into Mql this way, step 5 = test.

.

In general, I would make functions for each of the 5 steps.

.

Singular transformation in Mql.

https://www.mql5.com/ru/code/7359

 

Thanks for the detailed breakdown of how this singular decomposition algorithm should work. Items 1-3 are implemented. The problem remains with point 4, because I'm not yet able to create a working dll with export function rmatrixsvd(...), as I wrote before,

because of adding extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(...) to original C++ code, I get errors... Although if you compile just bool rmatrixsvd(...) there are no errors... but I need an exportable function... That's where it gets confusing...

Thanks for the help.

 

Regarding point 4 (and all the others). rmatrixsvd has nothing to do with it.

Neither does the singular decomposition algorithm. These items are related to

to send/receive data from/to Dll.

.

The prototype function to write for item. 4:

void Convert_real_2d_array_to_double(

const ap::real_2d_array & arr,

double * data,

int & lines,

int & columns

);

.

That is, you need to learn how to get the number of rows, columns and data from ap::real_2d_array.

.

From this:

const ap::real_2d_array & arr

---->>>

get it:

double * data,

int & lines,

int & columns

 

Thank you very much again for your time.

Once again I read all posts very carefully and it looks like I've finally figured out :-) what to do.

Indeed, the rmatrixsvd function itself is kind of a "workhorse" here and I don't need to try to export it,

you just need to put the load on the cart on time and then gently unload it to the right place when it's delivered

to its destination, figuratively speaking. Do I understand you correctly now?

In other words, I need to make these data converters (3 and 4) in C++ and work with them in MQL, i.e. they should be declared in MQL, and in DLL they

be declared as exportable, so that Metatrader could use them. Do I understand my problem correctly?

If it's so, and I think I understand you now, it's even better, because I wasn't sure how to link 2D and 1D arrays then.

Moreover, you can't declare array as a[ ][ ] in MQL, can you? I.e., the array should at least be declared as a[ ][100]. Is it so? Or am I mistaken?

And this is not very convenient because you do not know beforehand what the dimension of a two-dimensional array will be, while reserving memory for an array in advance is not the best way to go,

But there's no such a problem in C++? So, a two-dimensional array may be figuratively called "rubber". Is it so? Or is there some subtleties in C++ too?

I'd also like to ask you about Borland Builder 2009. Maybe it's not as glitchy as the 6-th one? Is it actually possible to work with it?

Because alsu said he's a retarder, as far as I know. :-) But as far as I've understood you program using Visual Studio? Is it cooler? And without glitches? What's the latest version right now?

I'm glad I got to the bottom of my problem with your help. Now I'll try to implement it all...

 
boysn >> :

Especially since you can't declare array as a[ ][ ] in MQL, can you? That is, you should at least declare it as a[ ][100]. Is it so? Or am I mistaken?

And this is not very convenient because you do not know beforehand what the dimension of a two-dimensional array will be, while reserving memory for an array in advance is not the best way to go,

Great! :-) I'm very glad the process is going somewhere :-).

.

Of course, you can declare two-dimensional arrays in Mql4.

And in the same way you can import functions from DLL

#import myLib

void showMatrix(double & array[][], int rows, int cols);

#import

.

But there is a nuance here: In C, we declare a function that accepts a one-dimensional array,

the number of rows and columns void showMatrix(double *array, int rows, int cols);

And the array works as a one-dimensional array, addressing in which is arranged in a loop:

for(line = 0 ... MAX_COL-1)
for(column = 0 ... MAX_COL-1)
array[line*MAX_COL + column] = data[line][column];

.

That is, Mql throws a two-dimensional array with a continuous buffer.

.

Just don't step on the same rake - functions from step 3 and 4 are used inside your Dll,

inside the interface function of the Dll-ins that will take the one-dimensional arrays with number of rows/columns from Mql.

It will convert them to ap::real_2d_array, pass to rmatrixsvd

and puts the result into the output buffer, which must have the correct row and column

must be correct.

.

The output buffer should be reserved in advance, of course - it should be done in Mql.

If you don't know the dimensions, my opinion is that you should make

a one-dimensional array of a high dimensionality, for example

double out[2500];

and a one-element array for output values of rows/columns

double raws[1];

double cols[1];

.

Visual Studio is cooler. Especially with Visual Assist. I don't know how STL works in Debuilder. There are almost 100% problems with Unicode.

The Win SDK's help doesn't compare to MSDN. Rumor has it that to integrate with delphi the Borland compiler

for the pluses has undergone non-positive changes.

.

And working with memory is a topic for a class.

 

Everything seems to be theoretically clear, I'll get down to implementation, and then we'll see :-). "The eyes are afraid, but the hands do the work..."

Thanks again for the valuable guidance. I would really like to implement this algorithm... As usual, the idea is already far away strategically, but tactically and practically

I have to catch up with it. I hope I'll be able to do it. If I have any questions, please do not hesitate to help me with advice. Thank you!

 

I would like to clarify once again about the dimensionality of dynamic arrays.

In MQL, a one-dimensional array can be defined as array[ ], and then when the program knows the array's dimension N,

you can use the ArrayResize(array, N) function. A two-dimensional array can be defined as array[ ][100] only, i.e. the second dimensionality

should be known all the same, and if you don't know it, you should take the maximum so that it would be enough in any case. You can define in MQL

array[ ][ ]. The compiler will not complain about it but the ArrayResize function sets a new size in the first array dimension ,

There is no such function in MQL for the second dimension. If you define a two-dimensional array array array[N][M], the compiler will return an error saying

an integer, i.e. the dimensionality should be defined beforehand, at least the second array dimension.

Is it the same in C++? There's no way to get away from it, is there? Once again I'd like to clarify.

Singular decomposition uses AP Library for C++ (description in attached file). There are some functions in it which, as far as I understood, solve

problems of dynamic first and second dimension of arrays. Can I use them in my case inside the DLL when writing data converters?

void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Allocate memory for the array. This deletes the old array contents and frees the memory allocated for it, then allocates a new separate memory area with the size of (iHigh1-iLow1+1)*(iHigh2-iLow2+1) elements.
Numbering of elements in a new array by the first dimension starts with iLow1 and ends with iHigh1, the same for the second dimension.
Contents of the new array is not defined.

There is also the following function:

void setcontent(int iLow1, int iHigh1, int iLow2, int iHigh2, const T *pContent)
The method is similar to the setbounds() method with the exception that the contents of the pContent[] array is copied into it after memory allocation.
The pContent array contains a two-dimensional array written line by line, i.e. element [iLow1, iLow2] goes first, then [iLow1, iLow2+1], etc.

If I understood correctly, this is exactly the function I need, i.e. it makes a two-dimensional array from a one-dimensional one, i.e. it is essentially a converter.

Did I get it right?

 

AP library for C++

 
AP library for C++
Files:
 

MQL : in one-dimensional we change the dimension as we want, yes. Then we get everything by indexes (line * MAX_COL + col).

In two-dimensional, the 2nd dimension is fixed. That is, we cannot read matrix elements [15][32] from array a[100][100].

.

And I suggest that you check how the AP library functions work.

Don't stop at the Dll. Write an exe, it's easier to run and debug.

Insert the debug print.

Advice I can certainly give - but for advice, you need to test it -

write test code.

.

As for the contents of the array and the variables - it doesn't matter where -

better make it a rule to initialize them forcibly, rigidly.