Erreurs, bugs, questions - page 2577

 
fxsaber:

Puis division par zéro.

Ng...il y avait de l'espoir, mais comme toujours, seul le hardcore ))))

 
Vict:

ZS : peut-être qu'il ne faut pas s'embêter avec les chaînes de caractères du tout ? sauvegarder les tableaux dans wchar_t et les faire courir, et dans le µl convertir en chaîne de caractères si nécessaire https://www.mql5.com/ru/docs/convert/shortarraytostring

D'accord

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

WinAPI -> MQL5 x64

A100, 2018.05.29 14:11

Tout le règlement a été dit. Si vous voulez que cela fonctionne toujours - vous devez utiliser ushort, et si vous voulez comprendre pourquoi string cesse soudainement de fonctionner (ce qui fonctionnait hier) - vous pouvez utiliser string

 
Vict:

Ici, vous êtes en dehors des limites


Vous m'avez donné l'idée de vérifier la longueur de la chaîne initialisée dans StringInit(out, 165, 32) ;

L'aide de StringInit dit que le deuxième paramètre est la longueur de la chaîne, la longueur de la chaîne dans ma compréhension est le nombre de caractères de la chaîne.
Dans mon cas, la chaîne entrante comporte 164 caractères, j'ai donc mis 165 dans le deuxième paramètre, et j'ai essayé plus de *2, 330.

Utilisation dememcpy_s avec un pointeur,

memcpy_s(out, wcslen(data) * sizeof(wchar_t*), data, wcslen(data) * sizeof(wchar_t*));

Le résultat était le même, la fin de la chaîne dérive toujours du nombre de caractères, et il y a des fuites lors de l'analyse syntaxique.
Sans pointeur, la chaîne est également flottante.

Mais vous m'avez donné une idée et dans StringInit(out, 1400, 32) j'ai défini la taille du pointeur en octets, pas la longueur de la chaîne.
Et voilà, miracle, la chaîne est devenue sans caractères de sortie supplémentaires, sans problèmes d'analyse, et sans une seule fuite.
Je veux noter que c'est avec le pointeur dans sizeof, sans le pointeur la chaîne flotte.

Cela pose une question aux développeurs, est-ce que l'aide sur StringInit est correcte ???
Ne confond-on pas, dans l'aide ou dans la fonction StringInit elle-même, la longueur de la chaîne avec la taille de la chaîne ?
En général maintenant si vous utilisez memcpy cela fonctionne correctement si vous passez la taille du pointeur et StringInit est initialisé avec cette taille, pas la longueur !

 
A100:

D'accord

Oui, je suis aussi d'accord. Mais il n'est pas toujours pratique d'utiliser une chaîne de caractères comme un tableau, surtout lorsque cette chaîne doit être transmise par plusieurs fonctions.
Les pointeurs sont plus pratiques dans ce cas, vous n'avez pas besoin de remplir à nouveau ce tableau dans chaque fonction de transit, et en plus vous entrez un paramètre supplémentaire pour le tableau, sa taille.

 
A100:

Ainsi, vous avez simplement alloué un tampon délibérément surdimensionné (repoussé la limite) et l'erreur n'apparaît pas - parce qu'elle était à la limite.

C'est ce que je pensais aussi, la longueur de la corde est de 164, set 165, set 330.
330 n'est manifestement pas une limite de la longueur des chaînes, si l'on compte les chaînes en caractères.
Il s'avère que ce n'est pas la longueur, mais la taille des octets.
Mais l'aide suggère le contraire, que ce devrait être la longueur dansStringInit.

En général, d'après ce que j'ai compris, le type de chaîne de caractères de mql est un pointeur et vous devez traiter ce type comme un pointeur.

 
J'ai également décidé de vérifier la chaîne reçue dans la dll, pour la présence du terminal null.
Le zéro est présent
for (int index = 0; index <= wcslen(data); ++index)
   wcout << static_cast<int>(data[index]) << " ";
123 34 101 34 58 34 97 103 103 84 114 97 100 101 34 44 34 69 34 58 49 53 54 57 54 50 52 50 50 57 50 51 54 44 34 115 34 58 34 66 84 
67 85 83 68 84 34 44 34 97 34 58 49 54 54 50 49 57 49 55 53 44 34 112 34 58 34 56 50 48 50 46 49 48 48 48 48 48 48 48 34 44 34 113 
34 58 34 48 46 48 51 51 50 51 48 48 48 34 44 34 102 34 58 49 56 51 57 54 49 54 55 50 44 34 108 34 58 49 56 51 57 54 49 54 55 50 44 
34 84 34 58 49 53 54 57 54 50 52 50 50 57 50 51 49 44 34 109 34 58 116 114 117 101 44 34 77 34 58 116 114 117 101 125 0
 
Roman:

Si vous insistez, faites-le à votre façon.

 
Roman:

C'est ce que je pensais aussi. La longueur de la corde est de 164, j'ai mis 165 et puis 330.
330 n'est évidemment pas une limite de longueur de chaîne si l'on compte les chaînes en caractères.
Il s'avère que ce n'est pas la longueur, mais la taille des octets.
Mais l'aide suggère le contraire, que ce devrait être la longueur dans StringInit.

En général, d'après ce que j'ai compris, le type de chaîne de caractères de mql est un pointeur et vous devez traiter ce type comme un pointeur.

Le type mql string est une structure qui contient un pointeur, la longueur de la chaîne et éventuellement autre chose.

Lorsque vous transmettez une chaîne de caractères à la DLL, seul le pointeur est transmis. La longueur de la chaîne doit être passée manuellement.

Et veillez toujours à ne pas surdimensionner la corde.

Toutes les modifications de la taille de la ligne se font uniquement du côté MQL.

Du côté des DLL, vous devez lire attentivement l'aide des fonctions que vous utilisez. C'est le seul problème que vous avez.

sizeof( wchar_t* ) renvoie la taille du pointeur. Ce n'est pas du tout ce dont vous avez besoin.

 
Koldun Zloy:

Le type mql string est une structure qui contient un pointeur, la longueur de la chaîne et éventuellement autre chose.

Lorsque vous transmettez une chaîne de caractères à la DLL, seul le pointeur est transmis. La longueur de la chaîne doit être passée manuellement.

Et veillez toujours à ne pas surdimensionner la corde.

Toutes les modifications de la taille de la chaîne se font uniquement du côté du MQL.

Du côté des DLL, vous devez lire attentivement l'aide des fonctions que vous utilisez. C'est le seul problème que vous avez.

sizeof( wchar_t* ) renvoie la taille du pointeur. Ce n'est pas du tout ce dont vous avez besoin.

Bien, j'alloue un tampon pour la chaîne out, et l'initialise avec des espaces.
Puis je passe cette chaîne (pointeur) à la dll.

string out;
StringInit(out, 1400, 32);

Func(out);

Dans la dll, les données wchar_t* sont copiées vers out, c'est-à-dire également un pointeur. Logiquement, il ne devrait y avoir aucun problème.
D'après ce que je comprends de l'aide, la fonction StringInit doit définir la longueur de la chaîne.
Mais j'ai encore quelques problèmes avecla fonction StringInit elle-même ; j'ai spécifié la longueur de la chaîne et j'ai eu des problèmes lorsque j'ai indiqué la taille du pointeur.
Je ne comprends pas à quel transfert manuel de longueur de corde vous faites allusion.

Et si vous utilisez sizeof(wchar_t) sans pointeur, la chaîne commence à flotter avec des caractères supplémentaires, ce qui pose des problèmes d'analyse et de fuite.
Pour passer des chaînes de caractères dans une dll, j'ai utilisé l'exemple de Renat, dans son article sur la façon d'écrire une dll.
Mais pour une raison quelconque, si je le passe sans le pointeur sizeof(wchar_t), la chaîne est flottante, alors qu'avec le pointeur sizeof(wchar_t*) il n'y a pas de problème.
Cela me semble logique, je copie une chaîne de caractères comme un pointeur, la taille devrait être passée au pointeur, pas le type.

 

Essayez

StringInit(out, 200, 32);
...

if ( memcpy_s(out, 200*sizeof(wchar_t), data, wcslen(data)*sizeof(wchar_t)+sizeof(L'\0')) ) {
   // что-то пошло не так
}

Après que cela ait fonctionné, je porterais mon attention sur wcscpy.