エラー、バグ、質問 - ページ 2577

 
Igor Makanu:

そのオプションは知っています。

次にゼロで割る

 
fxsaber:

次にゼロで割る

Np...希望はあったが、相変わらずハードコアしかない ))))

 
Vict:

ZS: 多分、文字列を全くいじらないのでしょう。配列をwchar_tで保存して、それをレースし、必要ならµlの中で文字列に変換します。https://www.mql5.com/ru/docs/convert/shortarraytostring

同意

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

WinAPI -> MQL5 x64

A100, 2018.05.29 14:11

ルールはすべて言い尽くされている。常に動作させたい場合は - ushort を使用する必要があり、string が突然動作しなくなった理由(昨日まで動作していたもの)を理解したい場合は - string を使用します。

 
Vict:

へたをすると


StringInit(out, 165, 32)で初期化された文字列の長さを確認するアイデアをいただきました。

StringInitのヘルプによると、第2パラメータは文字列長となっていますが、私の理解では文字列長とは文字列の文字数のことです。
私の場合、入力される文字列が164文字なので、第2パラメータに165を入れ、*2, 330以上を試しました。

ポインタでmemcpy_sを 使用する。

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

結果は同じで、文字列の末尾が常に文字数分流れてしまい、パース時に漏れが発生しました。
ポインタがないと、文字列も浮いてしまいます。

しかし、あなたがアイデアをくれたので、StringInit(out, 1400, 32) で、文字列長ではなく、ポインタサイズをバイト数で設定しました。
そして、奇跡的に、文字列は余分な出力文字なしになり、パースも問題なく、漏れも一つもありませんでした。
注意したいのは、sizeofにポインタがある状態で、ポインタがないと文字列が浮いてしまうことです。

このことは、開発者に、StringInitに関するヘルプは正しいのか?
ヘルプやStringInit関数 自体で、文字列の長さと文字列の大きさがごっちゃになっていないでしょうか?
一般に、memcpy を使用する場合、ポインタのサイズを渡すと正しく動作し、StringInit は長さではなく、このサイズで初期化されます!

 
A100:

同意

はい、私もそう思います。しかし、文字列を配列として使用することは、特にこの文字列をいくつかの関数に渡す必要がある場合、必ずしも便利ではありません。
この場合、ポインターはより便利です。各遷移関数でこの配列を再補充する必要がなく、さらに配列のパラメータとしてそのサイズを入力することができます。

 
A100:

つまり、意図的にオーバーサイズのバッファを割り当てた(境界を押し戻した)ため、エラーが表示されないだけなのです。

私もそう思っていました、弦長は164、セット165、セット330です。
330は、文字列を文字数で数えると、明らかに文字列の長 さの境界線ではありません。
長さではなく、バイトの大きさであることが判明した。
しかし、ヘルプを見ると、逆にStringInitの さを指定するようです。

一般に、mqlの文字列型はポインタであり、この型をポインタと同様に扱うべきであると私は理解しています。

 
また、受信した文字列をDLLでチェックし、端末のNULLの有無を確認することにしました。
ゼロが存在する
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:

どうしてもと言うなら、好きにすればいい。

 
Roman:

私もそう思っていました。 文字列の長さが164なので、165にしてから330にしました。
330は、文字列を文字数で数えると明らかに文字列の長さの 境界線ではありません。
長さではなく、バイトの大きさであることが判明した。
しかし、ヘルプを見ると、逆にStringInitの さを指定するようです。

一般に、mqlの文字列型はポインタであり、この型をポインタと同様に扱うべきであると私は理解しています。

mql型のstringは、ポインタ、文字列の長さ、および場合によってはそれ以外のものを含む構造体です。

DLLに文字列を渡すと、ポインタだけが渡されます。文字列の長さは、手動で渡す必要があります。

そして、必ず文字列のサイズをオーバーしないようにします。

文字列サイズの変更はすべてMQL側のみです。

DLL側では、使用する関数のヘルプをよく読んでおく必要があります。これが唯一の問題点です。

sizeof( wchar_t* ) はポインタのサイズを返します。そんなものは全く必要ない。

 
Koldun Zloy:

mql型のstringは、ポインタ、文字列の長さ、および場合によってはそれ以外のものを含む構造体です。

DLLに文字列を渡すと、ポインタだけが渡されます。文字列の長さは、手動で渡す必要があります。

そして、必ず文字列のサイズをオーバーしないようにします。

ラインサイズの変更はすべてMQL側のみです。

DLL側では、使用する関数のヘルプをよく読んでおく必要があります。これが唯一の問題点です。

sizeof( wchar_t* ) はポインタのサイズを返します。これは全く必要ないものです。

そうそう、文字列outのバッファを確保して、空白で初期化するんだ。
そして、この文字列(ポインタ)をDLLに渡しています。

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

Func(out);

dllでは,wchar_t*のデータはoutにコピーされ,つまりポインタにもなります.論理的には何の問題もないはずです。
ヘルプによると、StringInit関数で文字列の長さを設定するように理解しました。
しかし、StringInit関数 自体にはまだ問題があります。文字列の長さを指定したのに、ポインタのサイズを指したら変なことになったのです。
マニュアルの文字列の長さの移動というのがよくわからない。

また、ポインタなしで sizeof(wchar_t) を使うと、文字列が余分な文字で浮遊し始め、パースやリークで問題が発生します。
dllに文字列を渡すために、私はRenatのdllの書き方の記事から、彼の例を使用しました。
しかし、sizeof(wchar_t)ポインタを付けずに渡すと、なぜか文字列が浮いてしまうのですが、sizeof(wchar_t*)ポインタを付けると問題ないです。
文字列をポインタとしてコピーするので、型ではなくポインタのサイズを渡す必要があるのは理にかなっていると思います。