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

 

J'ai en quelque sorte écrit quelque chose dans un fichier h


extern __declspec( dllexport) int __stdcall GetIntValue(int);

puis dans le cpp juste


int __stdcall GetIntValue(int)
 
Peut-être que le mot-clé extern serait utile.
 
alsu >> :

...


...et je préfère ne pas m'occuper des cordes du tout... Pourquoi en a-t-on besoin dans une dll ? C'est juste pour la beauté ?

Et Borland lui-même recommande d'utiliser char* ou char[], à la manière de Metatrader, si nécessaire.

 

Je pense que la manière correcte de le déclarer dans le constructeur est la suivante (je ne me souviens pas exactement)

extern "C" __declspec(dllexport) int __stdcall GetIntValue();

 
GarF1eld >> :

Je pense qu'il est correct de déclarer dans le builder quelque chose comme ceci (je ne me souviens pas exactement)

extern "C" __declspec(dllexport) int __stdcall GetIntValue();

Là ! Exactement !

 

Merci beaucoup pour ces conseils ! Cela a fonctionné avec cet exemple après extern "C" int __declspec(dllexport) __stdcall GetIntValue().

J'ai essayé avec les fonctions double et string, et ça a marché aussi. J'ai décidé d'appliquer les connaissances que j'ai acquises auprès de vous à une tâche pratique. Mais hélas... Je n'ai pas réussi, malheureusement.

Si vous le pouvez, aidez-moi encore une fois.

Il y a des fichiers dans le projet Bilder pour la création de DLL : UHsvd.h, Usvd.cpp et autres.

Le fichier UHsvd.h contient une fonction qui doit être exportée plus tard :

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int uneeded,
int vtneed,
int additionalmemory,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt) ;

Le fichier Usvd.cpp contient la même fonction, qui doit ensuite être exportée :

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int uneeded,
int vtneed,
int additionalmemory,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt)

{

........

}

Je commence à construire une DLL dans Bilder dans cette variante, tout se "construit", tout fonctionne, aucune erreur.

Si je commence à faire des changements dans UHsvd.h, Usvd.cpp comme

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a,

.....), alors les erreurs de 2 à 19 apparaissent avec différentes variantes, c'est-à-dire que j'ai fait cette déclaration soit dans le fichier d'en-tête, soit dans le cpp... bien que, d'après ce que j'ai compris, il devrait être dans le fichier d'en-tête (alors il n'y a que 2 erreurs) :

[Erreur BCC32] Usvd.cpp(128) : E2356 Type mismatch in redeclaration of '__stdcall rmatrixsvd(ap::real_2d_array,int,int,int,int,ap::real_1d_array &,ap::real_2d_array &,ap::real_2d_array &)'
[Erreur BCC32] UHsvd.h(111) : E2344 Déclaration antérieure de '__stdcall rmatrixsvd(ap::real_2d_array,int,int,int,int,ap::real_1d_array &,ap::real_2d_array &,ap::real_2d_array &)'.

Si je comprends bien, il y a une différence... Mais je ne le comprends pas complètement... :-(

J'espère vraiment votre aide et votre soutien...

 

boysn писал(а) >> {...}

Si vous le pouvez, aidez-nous encore une fois.

Il y a des fichiers dans le projet Bilder pour créer une DLL : UHsvd.h, Usvd.cpp et d'autres.

Le fichier UHsvd.h comporte une fonction qui doit ensuite être exportée :

bool rmatrixsvd(ap::real_2d_array a,
int m,
int n,
int non désiré,
int vtneeded,
int mémoire supplémentaire,
ap::real_1d_array& w,
ap::real_2d_array& u,
ap::real_2d_array& vt) ; {...}

Si j'ai bien compris, ap::real_1d_array est une classe. Et ap::real_1d_array & est une référence à un objet de classe.

Mais mon cher, vous ne pouvez passer que le double myData[] comme paramètres à la Dll,

qui ressemblera à un double * dans les fonctions.

 
jartmailru писал(а) >>

Si je comprends bien, ap::real_1d_array est une classe. Et ap::real_1d_array & est une référence à l'objet de la classe.

Mais mon cher, seul le double myData[] peut être passé à la Dll comme paramètres,

qui, dans les fonctions, ressemblera à un double *.

Je suis tout à fait d'accord avec vous. Je vais le déclarer comme double dans MQL lors de l'importation. Mais pour l'instant, j'ai du mal à créer la DLL elle-même dans C++ Builder 2009. J'obtiens des erreurs lors de sa construction. Si je n'utilise pas la déclaration

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a, ...., ....) alors la bibliothèque se compile dans Bilder avec succès, sans problèmes. Maintenant, je ne sais pas comment créer correctement la déclaration des fonctions d'exportation dans le projet Bilder :-(, afin d'obtenir

DLL fonctionnelle avec possibilité d'exporter la fonction rmatrixsvd.

 
boysn >> :

Je suis tout à fait d'accord avec vous. Je le déclarerai comme double dans MQL lorsque je l'importerai. Mais pour l'instant, j'ai du mal à créer la DLL elle-même dans C++ Builder 2009. J'obtiens des erreurs lors de sa construction. Si je n'utilise pas la déclaration

extern "C" bool __declspec(dllexport) __stdcall rmatrixsvd(ap::real_2d_array a, ...., ....) alors la bibliothèque se compile dans Bilder avec succès, sans problèmes. Maintenant, je ne sais pas comment créer correctement la déclaration des fonctions d'exportation dans le projet Bilder :-(, pour obtenir

DLL de travail avec la possibilité d'exporter la fonction rmatrixsvd.

Brrr. Vous semblez être étrangement d'accord avec moi.

.

En fait, il s'agit d'écrire "adaptateur" ou "pont".

"Adaptateur" du point de vue que les paramètres de la fonction exportée

doit correspondre aux paramètres que le metatrader peut passer,

. c'est-à-dire que vous avez besoin d'une fonction supplémentaire qui transmet l'appel à l'endroit où vous voulez qu'il aille.

Et "pont" du point de vue qu'il n'est pas nécessaire pour la fonction

que vous déclarez faire le travail lui-même.

Et vice versa - il n'est pas nécessaire d'appeler la fonction qui effectue le travail.

.

En d'autres termes, vous devez séparer l'interface et l'implémentation, c'est-à-dire que l'implémentation peut être construite sur des classes

. et les fonctions qui se trouvent en dehors de la Dll et dont personne n'aura jamais connaissance.

.

Mais prenons un exemple.

.

Vous devez déclarer la fonction comme ceci :

extern "C" bool __declspec(dllexport) __stdcall RMatrixSVD_DLL_ADAPTER(double * in1, double * in2, double * out)

// bien sûr, vous passerez également le nombre de lignes et de colonnes ici.

{

//convertit les paramètres d'entrée en ap::real_2d_array

ap::real_2d_array a1 = convertPDoubleToReal2DArray(in1) ;

ap::real_2d_array a2 = ;

.

//calculer

ap::real_2d_array a3 ;

rmatrixsvd(a1, a2, a3) ;

.

//traduire le résultat de a3 en out

convertReal2DArrayToPDouble(a3, out) ;

.

retour ;
}

.

Ici - bien sûr - la fonction rmatrixsvd

n'est pas déclaré comme extern "C" ou __stdcall ou __declspec etc.

Parce que ça fait partie de l'implémentation interne, cachée.

 

Désolé, je n'ai pas bien compris, malheureusement...

Sur http://alglib.sources.ru/, j'ai téléchargé l'implémentation C++ (code) dont j'ai besoin. Si vous le voulez bien, jetez un coup d'œil à l'archive ci-jointe de 100KB. Cet algorithme possède de nombreuses fonctions auxiliaires, le nombre total de lignes de code est d'environ 3000 lignes... Je pense que oui.

C'est écrit sur le site web, c'est-à-dire que c'est trop, et il est assez difficile de le traduire en MQL... Vous devez comprendre l'algorithme lui-même pour le traduire correctement. Pour le moment, c'est un peu compliqué pour moi. C'est pourquoi j'aimerais utiliser C++ Builder 2009 pour créer une dll avec ce code prêt à l'emploi et appeler la fonction rmatrixsvd(...) dont j'ai besoin dans la dll. C'est là que j'ai été surpris... où et comment le déclarer correctement... Avec ce code, sans changer une ligne ici, la DLL est construite, sans erreurs. Mais dès que je mets extern "C" bool __declspec(dllexport) __stdcall dedans, j'obtiens des erreurs...

Merci pour votre temps.

Dossiers :
svdy1e.cpp.zip  94 kb