Question sur les DLL ...... - page 6

 
Au fait, c'est une bonne chose http://www.parashift.com/c++-faq-lite/index.html.
 
La question est-elle toujours pertinente pour l'auteur ? Je suis en train d'écrire une dll pour moi-même, je peux vous donner un petit exemple.
 
Oui, c'est vrai ! !! J'ai résolu le problème de la dll grâce à vous ! Merci ! Mais il y a des choses que je n'arrive pas à comprendre comment les mettre dans la dll !
 

Les fonctions sont appelées selon certaines règles - la convention d'appel. MT4 est assuré de fonctionner avec les fonctions qui adhèrent à __stdcall (un cas particulier de variante de règle). Pour être sûr que la fonction exportée utilise les règles susmentionnées, elle doit ressembler à ceci : void __stdcall AnyFn() ;

2. Je connais deux façons de faire de l'export de fonction de bibliothèque - avec __declspec(dllexport) et avec le fichier def (c'est plus facile, sinon il faut se battre avec le décodage de fonction en plus). Dans VS, pour inclure le fichier def dans le projet, il faut d'abord l'ajouter aux fichiers du projet, puis ajouter le nom du fichier à : project properties/composer/input/module definition file.

P.S : Le projet d'exemple avec le fichier def se trouve dans : répertoire terminal\ experts\samples\DLLSample.



 

PASSER DES PARAMÈTRES À UNE FONCTION DLL

1. Lors du passage d'une variable de type chaîne, un tableau de char (caractère ANSI, prend 1 octet) est passé à la DLL.

#import "myLib.dll"

void fn(string var);

#import

DLL:

void __stdcall fn(char *pointer) {}


2. Le passage d'un int ou d'un double à la bibliothèque entraîne la copie de la variable. Par conséquent, lorsque vous modifiez la variable dans la dll, il n'y a pas de changement dans la dll :

#import "myLib.dll"

void fn(int var);

void fn(double var);

#import

DLL:

void __stdcall fn(int var) {}


3. Pour pouvoir modifier les variables int et double déclarées en MQL, il faut passer des tableaux :

#import "myLib.dll"

void fn(int var[]);

void fn(double var[]);

#import

DLL:

void __stdcall fn(int *var) {}

void __stdcall fn(double *var) {}


4. Quand on passe un tableau à partir d'une chaîne de caractères, la structure MqlStr est passée à la DLL :

МКЛ прототип:

#import "myLib.dll"

void fn(string var[]);

#import

DLL:
struct MqlStr
{
   int len;
   char *string;
};

void __stdcall fn(MqlStr *var) {}


P.S.

Lorsqu'un tableau ou une chaîne de caractères (string) est transmis à la DLL, il s'agit en fait d'un pointeur vers une section de mémoire (pointeur) qui est transmis à la bibliothèque comme suit

void __stdcall fn(int *pointer) {} // comme ceci. De cette façon, vous pouvez travailler comme un tableau, par exemple, pointeur[4] = 4.

void __stdcall fn(int &reference) {} // ou ainsi. Mais nous n'aurons accès qu'à un seul élément, ce qui est pertinent lorsqu'on passe un tableau d'un seul élément à la bibliothèque.

 
#import "myLib.dll"

void fn(string var);

#import

DLL:

void __stdcall fn(char *pointer) {}

Je n'ai pas trouvé d'explication pour l'astérisque devant le pointeur, à quoi sert-il ? N'est-il pas possible de s'en passer ? ? ????

Et une question sur la manière de récupérer le texte d'une dll ? ??

 
VOLDEMAR:

Je n'ai pas trouvé d'explication pour l'astérisque devant le pointeur, à quoi sert-il ? N'est-il pas possible de s'en passer ? ? ????

Et une question sur la manière de récupérer le texte d'une dll ? ??

Vous n'avez pas besoin d'en tirer un texte. Du moins pas cette année.
 

1. Transfert d'une chaîne de caractères vers l'IDC :

DLL:
#include <string.h>
void __stdcall Temp(char *mqlStr)
{
   size_t mqlStringSize = strlen(mqlStr);
   char stroka[] = "DLL string";          // Эту строку передадим в MQL.
   if(strlen(stroka) > mqlStringSize)
      stroka[mqlStringSize] = '\0';       // Добавляем нуль-терминатор (обозначает конец строки).
   strcpy(mqlStr, stroka);
   return;
}

MQL:
#include "WaveCounter.dll"
void Temp(string str);
#include
int start()
{ 
   string str = "wwwwwsff";    // Задаем длину строки; Если длина будет меньше необходимого, то строка будет урезана.
   Temp(str); 
   Alert(str); 
   return;
} 
2. Le signe * indique qu'il s'agit d'un pointeur. En bref, toute variable a non seulement une valeur, mais aussi une adresse où elle se trouve en mémoire. Les pointeurs peuvent fonctionner avec cette adresse. C'est un problème qui doit être bien compris, je pense que vous devriez consulter les livres sur le C++ ;
 
220Volt:

1. Transfert d'une chaîne de caractères vers l'IDC :

2. Le signe * indique qu'il s'agit d'un pointeur. En bref, toute variable a non seulement une valeur, mais aussi une adresse où elle se trouve en mémoire. Les pointeurs peuvent fonctionner avec cette adresse. Il s'agit d'une question qui doit être bien comprise. Vous pouvez donc consulter des ouvrages sur le C++ ;
C'est ce que je fais. J'utilise C++, je regarde des vidéos, je lis des livres. Maintenant, une grande partie de MKL 5 devient claire ........
 

Vous devez juste faire attention aux données globales de la bibliothèque. Les programmes MCL s'exécutent indépendamment les uns des autres (mais partagent des variables globales car ils sont dans le même thread), il est donc possible que plusieurs scripts écrivent et lisent au même emplacement mémoire (ce qui n'est pas bon). Cela nécessite une synchronisation, par exemple en utilisant des sections critiques. Je souligne que cela est vrai pour les données globales (déclarées en dehors des fonctions). Lorsque des fonctions sont appelées, leur propre ensemble indépendant de variables est créé.