Aiuto per risolvere un problema con l'importazione di una funzione da una dll - pagina 3

 

Non ringraziate :-). Farete tutto da soli :-).

Spiega i passi passo dopo passo:

.

#1 (prova uno, non devi farlo ;-) :

In C++, create una matrice con numero di righe MAX_ROW = 5...10, colonne MAX_COL = 5...10 (numeri a caso).

Fai un riempimento casuale di dati.

.

#2 (prova uno, non devi fare ;-) : risolvi il seguente problema:

La matrice del passo #1 deve essere rappresentata in forma unidimensionale.

creare un array unidimensionale doppio di dimensione=MAX_ROW*MAX_COL, dove i dati sono memorizzati secondo la formula

per(linea = 0 ... MAX_COL-1)

per(colonna = 0 ... MAX_COL-1)

array[linea*MAX_COL + colonna] = dati[linea][colonna];

.

#3: risolvere il seguente problema / come funzione

Si ottiene un array unidimensionale doppio dal passo (2), il numero di righe e colonne.

Devi mettere i dati di questo array in un oggetto ap::real_2d_array

.

#4: Si ottiene l'oggetto ap::real_2d_array / come funzione

Dovete convertirlo in un array unidimensionale doppio, ottenere il numero di righe e colonne.

.

#5 (prova uno, non devi fare ;-) :

Dovete convertire la matrice unidimensionale in una matrice bidimensionale (come nel passo 1).

Confronta la matrice risultante con la matrice originale del passo 1.

In caso di disadattamento, risolvete il problema.

.

Le funzioni principali che saranno necessarie sono le funzioni 3 e 4.

Passi 1,2 = allenamento, dovrai impacchettare i dati in Mql in questo modo, passo 5 = test.

.

In generale, farei delle funzioni per ognuno dei 5 passi.

.

Trasformazione singolare in Mql.

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

 

Grazie per la ripartizione dettagliata di come dovrebbe funzionare questo algoritmo di decomposizione singolare. I punti 1-3 sono implementati. Il problema rimane al punto 4, perché non sono ancora in grado di creare una dll funzionante con la funzione di esportazione rmatrixsvd(...), come ho scritto prima,

a causa dell'aggiunta di extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(...) al codice originale C++, ottengo errori... Anche se se si compila solo bool rmatrixsvd(...) non ci sono errori... ma quello di cui ho bisogno è una funzione esportabile... È qui che ci si confonde...

Grazie per l'aiuto.

 

Per quanto riguarda il punto 4 (e tutti gli altri). rmatrixsvd non ha niente a che fare con questo.

Nemmeno l'algoritmo di decomposizione singolare lo fa. Queste voci sono legate a

per inviare/ricevere dati da/a Dll.

.

La funzione prototipo da scrivere per l'elemento. 4:

void Convert_real_2d_array_to_double(

const ap::real_2d_array & arr,

doppio * dati,

int & linee,

int & colonne

);

.

Cioè, dovete imparare come ottenere il numero di righe, colonne e dati da ap::real_2d_array.

.

Da questo:

const ap::real_2d_array & arr

---->>>

prendilo:

doppio * dati,

int & linee,

int & colonne

 

Grazie ancora per il suo tempo.

Ancora una volta ho letto tutti i post molto attentamente e sembra che finalmente ho capito :-) cosa fare.

In effetti, la funzione rmatrixsvd stessa è una specie di "cavallo di battaglia" qui e non ho bisogno di provare ad esportarla,

devi solo mettere il carico sul carrello in tempo e poi scaricarlo delicatamente al posto giusto quando viene consegnato

verso la sua destinazione, in senso figurato. Ho capito bene adesso?

In altre parole, ho bisogno di fare questi convertitori di dati (3 e 4) in C++ e lavorare con loro in MQL, cioè dovrebbero essere dichiarati in MQL, e in DLL

essere dichiarati come esportabili, in modo che Metatrader possa usarli. Ho capito bene il mio problema?

Se è così, e credo di averti capito adesso, è ancora meglio, perché non ero sicuro di come collegare gli array 2D e 1D allora.

Inoltre, non potete dichiarare array come un[ ][ ] in MQL, vero? Cioè, l'array dovrebbe almeno essere dichiarato come a[ ][100]. È così o mi sbaglio?

E questo non è molto conveniente perché non si sa in anticipo quale sarà la dimensione di un array bidimensionale, mentre riservare la memoria per un array in anticipo non è il modo migliore di procedere,

Ma non c'è questo problema in C++? Quindi, un array bidimensionale può essere chiamato figurativamente "gomma". È così? O ci sono delle sottigliezze anche in C++?

Vorrei anche chiedervi di Borland Builder 2009. Forse non è così glitchato come quello del 6? È davvero possibile lavorarci?

Perché alsu ha detto che è un ritardatario, per quanto ne so. :-) Ma per quanto ho capito tu programmi usando Visual Studio? È più fresco? E senza glitch? Qual è l'ultima versione al momento?

Sono contento di essere arrivato in fondo al mio problema con il vostro aiuto. Ora cercherò di implementare il tutto...

 
boysn >> :

Soprattutto perché non si può dichiarare un array come un[ ][ ] in MQL, vero? Cioè, dovreste almeno dichiararlo come un[ ][100]. È così o mi sbaglio?

E questo non è molto conveniente perché non si sa in anticipo quale sarà la dimensione di un array bidimensionale, mentre riservare la memoria per un array in anticipo non è il modo migliore di procedere,

Grande! :-) Sono molto contento che il processo si stia muovendo da qualche parte :-).

.

Naturalmente, potete dichiarare array bidimensionali in Mql4.

E allo stesso modo si possono importare funzioni dalla DLL

#importare la mia libreria

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

#importare

.

Ma c'è una sfumatura qui: in C, dichiariamo una funzione che accetta un array unidimensionale,

il numero di righe e colonne void showMatrix(double *array, int rows, int cols);

E la matrice funziona come una matrice unidimensionale, il cui indirizzamento è organizzato in un ciclo:

per(linea = 0 ... MAX_COL-1)
per(colonna = 0 ... MAX_COL-1)
array[linea*MAX_COL + colonna] = dati[linea][colonna];

.

Cioè, Mql lancia un array bidimensionale con un buffer continuo.

.

Basta non calpestare lo stesso rastrello - le funzioni del passo 3 e 4 sono usate all'interno della vostra Dll,

all'interno della funzione di interfaccia della Dll-ine, che prenderà gli array unidimensionali con numero di righe/colonne da Mql.

Li convertirà in ap::real_2d_array, passandoli a rmatrixsvd

e mette il risultato nel buffer di uscita, che deve avere la riga e la colonna corrette

deve essere corretto.

.

Il buffer di uscita dovrebbe essere riservato in anticipo, naturalmente - dovrebbe essere fatto in Mql.

Se non conosci le dimensioni, la mia opinione è che dovresti fare

un array unidimensionale di alta dimensionalità, per esempio

doppio fuori[2500];

e un array a un elemento per i valori di uscita delle righe/colonne

doppio raws[1];

doppio cols[1];

.

Visual Studio è più figo. Soprattutto con Visual Assist. Non so come funziona STL in Debuilder. Ci sono quasi il 100% di problemi con Unicode.

L'aiuto di Win SDK non è paragonabile a MSDN. Si dice che per integrarsi con delphi il compilatore Borland

per i plus ha subito cambiamenti non positivi.

.

E lavorare con la memoria è un argomento per un corso.

 

Tutto sembra essere teoricamente chiaro, passerò all'implementazione e poi vedremo :-). "Gli occhi hanno paura, ma le mani fanno il lavoro..."

Grazie ancora per la preziosa guida. Vorrei davvero implementare questo algoritmo... Come al solito, l'idea è già lontana strategicamente, ma tatticamente e praticamente

Devo recuperare il tempo perduto. Spero di essere in grado di farlo. Se ho delle domande, non esitate ad aiutarmi con dei consigli. Grazie!

 

Vorrei chiarire ancora una volta la dimensionalità degli array dinamici.

In MQL, un array unidimensionale può essere definito come array[ ], e poi quando il programma conosce la dimensione N dell'array,

potete usare la funzione ArrayResize(array, N). Un array bidimensionale può essere definito solo come array[ ][100], cioè la seconda dimensionalità

dovrebbe essere conosciuto lo stesso, e se non lo si conosce, si dovrebbe prendere il massimo in modo che sia sufficiente in ogni caso. Si può definire in MQL

Il compilatore non se ne lamenterà, ma la funzione ArrayResize imposta una nuova dimensione nella prima dimensione dell'array ,

Non esiste una funzione simile in MQL per la seconda dimensione. Se si definisce un array bidimensionale array[N][M], il compilatore restituirà un errore che dice

un intero, cioè la dimensionalità dovrebbe essere definita in anticipo, almeno la seconda dimensione dell'array.

È lo stesso in C++? Non c'è modo di sfuggirne, vero? Ancora una volta vorrei chiarire.

La decomposizione singolare usa AP Library per C++ (descrizione nel file allegato). Ci sono alcune funzioni in esso che, per quanto ho capito, risolvono

problemi di prima e seconda dimensione dinamica degli array. Posso usarli nel mio caso all'interno della DLL quando scrivo convertitori di dati?

void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Alloca la memoria per l'array. Questo cancella il contenuto del vecchio array e libera la memoria allocata per esso, quindi alloca una nuova area di memoria separata con la dimensione di (iHigh1-iLow1+1)*(iHigh2-iLow2+1) elementi.
La numerazione degli elementi in un nuovo array per la prima dimensione inizia con iLow1 e finisce con iHigh1, lo stesso per la seconda dimensione.
Il contenuto del nuovo array non è definito.

C'è anche la seguente funzione:

void setcontent(int iLow1, int iHigh1, int iLow2, int iHigh2, const T *pContent)
Il metodo è simile al metodo setbounds(), eccetto che il contenuto dell'array pContent[] è copiato in esso dopo l'allocazione della memoria.
L'array pContent contiene un array bidimensionale scritto riga per riga, cioè l'elemento [iLow1, iLow2] va prima, poi [iLow1, iLow2+1], ecc.

Se ho capito bene, questa è esattamente la funzione di cui ho bisogno, cioè converte un array unidimensionale in uno bidimensionale, cioè è essenzialmente un convertitore.

Ho capito bene?

 

Libreria AP per C++

 
Libreria AP per C++
File:
 

MQL : in monodimensionale cambiamo la dimensione come vogliamo, sì. Poi otteniamo tutto per indici (linea * MAX_COL + col).

In bidimensionale, la seconda dimensione è fissa. Cioè, non possiamo leggere gli elementi della matrice [15][32] dall'array a[100][100].

.

E vi suggerisco di controllare come funzionano le funzioni della libreria AP.

Non fermatevi al Dll. Scrivete un exe, è più facile da eseguire e debuggare.

Inserire una stampa di debug.

Un consiglio che posso certamente dare - ma per un consiglio, bisogna testarlo -.

scrivere codice di prova.

.

Per quanto riguarda il contenuto dell'array e delle variabili - non importa dove -

meglio fare una regola per inizializzarli forzatamente, rigidamente.