Aide à résoudre un problème d'importation d'une fonction depuis une dll - page 3

 

Ne remerciez pas :-). Vous ferez tout vous-même :-).

Expliquer les étapes par étape :

.

#1 (testez-en un, vous n'êtes pas obligé de le faire ;-) :

En C++, créez une matrice avec un nombre de lignes MAX_ROW = 5...10, de colonnes MAX_COL = 5...10 (nombres aléatoires).

Faites en sorte que les données soient remplies de manière aléatoire.

.

#2 (test 1, vous n'avez pas à le faire ;-) : résoudre le problème suivant :

La matrice de l'étape 1 doit être représentée sous forme unidimensionnelle.

créer un tableau unidimensionnel double de taille=MAX_ROW*MAX_COL, où les données sont stockées selon la formule suivante

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

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

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

.

#3 : résoudre le problème suivant / en tant que fonction

On vous donne un tableau unidimensionnel double de l'étape (2), le nombre de lignes et de colonnes.

Vous devez placer les données de ce tableau dans un objet ap::real_2d_array.

.

#4 : Vous obtenez l'objet ap::real_2d_array / comme une fonction

Vous devez le convertir en un tableau unidimensionnel double, obtenir le nombre de lignes et de colonnes.

.

#5 (test un, vous n'avez pas à le faire ;-) :

Vous devez convertir le tableau unidimensionnel en une matrice bidimensionnelle (comme à l'étape 1).

Comparez la matrice résultante avec la matrice originale de l'étape 1.

En cas d'incompatibilité, trouvez une solution.

.

Les principales fonctions qui seront nécessaires sont les fonctions 3 et 4.

Etapes 1,2 = formation, vous devrez emballer les données dans Mql de cette façon, étape 5 = test.

.

En général, je créerais des fonctions pour chacune des 5 étapes.

.

Transformation singulière dans Mql.

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

 

Merci pour l'explication détaillée du fonctionnement de cet algorithme de décomposition singulière. Les points 1 à 3 sont mis en œuvre. Le problème reste au point 4, car je ne suis pas encore capable de créer une dll fonctionnelle avec la fonction d'exportation rmatrixsvd(...), comme je l'ai écrit auparavant,

à cause de l'ajout de l'extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(...) au code C++ original, j'obtiens des erreurs... Bien que si vous compilez juste bool rmatrixsvd(...) il n'y a pas d'erreurs... mais ce dont j'ai besoin est une fonction exportable... C'est là que ça devient confus...

Merci pour votre aide.

 

Concernant le point 4 (et tous les autres). rmatrixsvd n'a rien à voir avec cela.

L'algorithme de décomposition singulière non plus. Ces éléments sont liés à

pour envoyer/recevoir des données de/vers la Dll.

.

La fonction prototype à écrire pour l'élément. 4 :

void Convert_real_2d_array_to_double(

const ap::real_2d_array & arr,

double * données,

int & lines,

int & colonnes

) ;

.

Autrement dit, vous devez apprendre à obtenir le nombre de lignes, de colonnes et de données de ap::real_2d_array.

.

De ça :

const ap::real_2d_array & arr

---->>>

Prenez-le :

double * données,

int & lines,

int & colonnes

 

Merci encore une fois pour votre temps.

Une fois de plus, j'ai lu tous les messages très attentivement et il semble que j'ai enfin trouvé :-) ce qu'il faut faire.

En effet, la fonction rmatrixsvd elle-même est en quelque sorte un "cheval de bataille" ici et je n'ai pas besoin d'essayer de l'exporter,

il suffit de mettre le chargement sur le chariot à temps et de le décharger délicatement au bon endroit lorsqu'il est livré.

à sa destination, au sens figuré. Est-ce que je vous comprends bien maintenant ?

En d'autres termes, je dois réaliser ces convertisseurs de données (3 et 4) en C++ et les utiliser dans MQL, c'est-à-dire qu'ils doivent être déclarés dans MQL, et dans DLL ils...

soient déclarés comme exportables, afin que Metatrader puisse les utiliser. Est-ce que je comprends bien mon problème ?

Si c'est le cas, et je pense que je vous comprends maintenant, c'est encore mieux, parce que je ne savais pas comment lier les tableaux 2D et 1D à l'époque.

De plus, vous ne pouvez pas déclarer un tableau comme un[ ][ ] dans MQL, n'est-ce pas ? C'est-à-dire que le tableau devrait au moins être déclaré comme un[ ][100]. Est-ce vrai ? Ou est-ce que je me trompe ?

Et ce n'est pas très pratique car vous ne savez pas à l'avance quelle sera la dimension d'un tableau à deux dimensions, et réserver à l'avance de la mémoire pour un tableau n'est pas la meilleure façon de procéder,

Mais ce problème n'existe pas en C++... Ainsi, un tableau à deux dimensions peut être appelé, au sens figuré, "caoutchouc". C'est vrai ? Ou y a-t-il aussi des subtilités dans le C++ ?

J'aimerais également vous interroger sur Borland Builder 2009. Peut-être qu'il n'est pas aussi défectueux que le 6ème ? Est-il réellement possible de travailler avec elle ?

Parce qu'Alsu a dit qu'il était un attardé, pour autant que je sache. :-) Mais d'après ce que j'ai compris, vous programmez en utilisant Visual Studio ? C'est plus frais ? Et sans pépins ? Quelle est la dernière version en date ?

Je suis heureux d'avoir trouvé la solution à mon problème grâce à votre aide. Maintenant, je vais essayer de mettre tout ça en œuvre...

 
boysn >> :

D'autant plus que vous ne pouvez pas déclarer un tableau comme un[ ][ ] dans MQL, n'est-ce pas ? C'est-à-dire que vous devriez au moins le déclarer comme un[ ][100]. Est-ce vrai ? Ou est-ce que je me trompe ?

Et ce n'est pas très pratique car vous ne savez pas à l'avance quelle sera la dimension d'un tableau à deux dimensions, et réserver à l'avance de la mémoire pour un tableau n'est pas la meilleure façon de procéder,

Super ! :-) Je suis très heureux que le processus avance :-).

.

Bien sûr, vous pouvez déclarer des tableaux à deux dimensions dans Mql4.

Et de la même manière, vous pouvez importer des fonctions depuis une DLL

#import myLib

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

#import

.

Mais il y a une nuance : en C, nous déclarons une fonction qui accepte un tableau unidimensionnel,

le nombre de lignes et de colonnes void showMatrix(double *array, int rows, int cols) ;

Et le tableau fonctionne comme un tableau unidimensionnel, dont l'adressage est organisé en boucle :

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

.

C'est-à-dire que Mql lance un tableau bidimensionnel avec un tampon continu.

.

Ne marchez pas sur le même râteau - les fonctions des étapes 3 et 4 sont utilisées dans votre Dll,

dans la fonction d'interface de la Dll-ine, qui prendra les tableaux unidimensionnels avec le nombre de lignes/colonnes de Mql.

Il les convertira en ap::real_2d_array, et les passera à rmatrixsvd.

et place le résultat dans le tampon de sortie, qui doit avoir la ligne et la colonne correctes.

doit être correcte.

.

Le tampon de sortie doit être réservé à l'avance, bien sûr - cela doit être fait dans Mql.

Si vous ne connaissez pas les dimensions, mon avis est que vous devriez faire

un tableau unidimensionnel de grande dimension, par exemple

double out [2500] ;

et un tableau à un élément pour les valeurs de sortie des lignes/colonnes

double raws[1] ;

double cols[1] ;

.

Visual Studio est plus cool. Surtout avec l'assistance visuelle. Je ne sais pas comment fonctionne la STL dans Debuilder. Il y a presque 100% de problèmes avec Unicode.

L'aide du SDK Win n'est pas comparable à celle de MSDN. La rumeur veut que pour s'intégrer à delphi, le compilateur Borland

pour les plus a subi des changements non positifs.

.

Et travailler avec la mémoire est un sujet pour un cours.

 

Tout semble être clair en théorie, je vais passer à la mise en œuvre, et ensuite nous verrons :-). "Les yeux ont peur, mais les mains font le travail..."

Merci encore pour ces précieux conseils. J'aimerais vraiment mettre en œuvre cet algorithme... Comme d'habitude, l'idée est déjà loin stratégiquement, mais tactiquement et pratiquement

Je dois le rattraper. J'espère que je pourrai le faire. Si j'ai des questions, n'hésitez pas à me donner des conseils. Merci !

 

J'aimerais clarifier une fois de plus la question de la dimensionnalité des tableaux dynamiques.

En MQL, un tableau unidimensionnel peut être défini comme array[ ], puis lorsque le programme connaît la dimension N du tableau,

vous pouvez utiliser la fonction ArrayResize(array, N). Un tableau à deux dimensions peut être défini comme tableau[ ][100] seulement, c'est-à-dire que la deuxième dimensionnalité

doit être connue tout de même, et si on ne la connaît pas, il faut prendre le maximum pour qu'elle soit suffisante de toute façon. Vous pouvez définir dans MQL

Le compilateur ne s'en plaindra pas, mais la fonction ArrayResize définit une nouvelle taille dans la première dimension du tableau ,

Il n'existe pas de fonction de ce type dans MQL pour la deuxième dimension. Si vous définissez un tableau bidimensionnel array[N][M], le compilateur renverra une erreur disant

un nombre entier, c'est-à-dire que la dimension doit être définie au préalable, au moins la deuxième dimension du tableau.

Est-ce que c'est la même chose en C++ ? Il n'y a aucun moyen d'y échapper, n'est-ce pas ? Une fois de plus, j'aimerais clarifier les choses.

La décomposition singulière utilise la bibliothèque AP pour C++ (description dans le fichier joint). Il contient certaines fonctions qui, d'après ce que j'ai compris, permettent de résoudre

les problèmes de dynamique de la première et de la deuxième dimension des tableaux. Puis-je les utiliser dans mon cas à l'intérieur de la DLL lors de l'écriture des convertisseurs de données ?

void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Allouer de la mémoire pour le tableau. Cela supprime le contenu de l'ancien tableau et libère la mémoire qui lui était allouée, puis alloue une nouvelle zone de mémoire séparée avec la taille de (iHigh1-iLow1+1)*(iHigh2-iLow2+1) éléments.
La numérotation des éléments dans un nouveau tableau par la première dimension commence par iLow1 et se termine par iHigh1, de même pour la deuxième dimension.
Le contenu du nouveau tableau n'est pas défini.

Il existe également la fonction suivante :

void setcontent(int iLow1, int iHigh1, int iLow2, int iHigh2, const T *pContent)
La méthode est similaire à la méthode setbounds(), sauf que le contenu du tableau pContent[] y est copié après l'allocation de mémoire.
Le tableau pContent contient un tableau bidimensionnel écrit ligne par ligne, c'est-à-dire que l'élément [iLow1, iLow2] va en premier, puis [iLow1, iLow2+1], etc.

Si j'ai bien compris, c'est exactement la fonction dont j'ai besoin, c'est-à-dire qu'elle convertit un tableau unidimensionnel en un tableau bidimensionnel, c'est-à-dire qu'il s'agit essentiellement d'un convertisseur.

Est-ce que j'ai bien compris ?

 

Bibliothèque AP pour C++

 
Bibliothèque AP pour C++
Dossiers :
 

MQL : en unidimensionnel, nous changeons la dimension comme nous le voulons, oui. Ensuite, nous récupérons tout par index (ligne * MAX_COL + col).

En bidimensionnel, la 2e dimension est fixe. Autrement dit, nous ne pouvons pas lire les éléments de la matrice [15][32] à partir du tableau a[100][100].

.

Et je vous suggère de vérifier comment fonctionnent les fonctions de la bibliothèque AP.

Ne vous arrêtez pas à la Dll. Écrivez un exe, c'est plus facile à exécuter et à déboguer.

Insérer une impression de débogage.

Je peux certainement donner des conseils, mais pour les conseils, il faut les tester.

écrire le code de test.

.

Quant au contenu du tableau et des variables - quel que soit l'endroit où il se trouve -, il n'y a pas d'erreur.

il vaut mieux faire une règle pour les initialiser de manière forcée, rigide.

Raison: