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

 
Koldun Zloy:

コピーされた文字列が、割り当てられたバッファサイズより大きかったり小さかったりした場合はどうなるのでしょうか?

もし小さければ問題ありません。通常、文字列バッファは 常に文字列自体よりわずかに大きくなります(ただし、これは事実ではありません!)。

しかし、それ以上書くと、ほぼ間違いなく端末がクラッシュします。
また、クラッシュはすぐには発生せず、次に動的メモリを使用する作業(配列や文字列バッファの再割り当て)、またはシャットダウン時に、使用したMQLプログラムのメモリがシステムに戻されたときに発生する可能性が高いです。

 
Ilyas:

1. MQLではUnicodeのみ、そのため文字サイズは2バイトです。

2. 文字列は構造体(バッファサイズ4バイト、ポインタサイズ8バイト)です。


文字列にコピーするのは

うまくいかない場合は、他の場所でエラーを発見する必要があります。

はい、最もシンプルな機能です

wcscpy(out, data);

と問題を起こす。ラインは均一にコピーされているが、大きなスキップがある。つまり、コピーに遅れが生じているのです。
そのため、他の機能も試されており、これも正しく使用すれば問題が発生する。
mutex、recursive_mutex、lock_guardなど、あらゆる種類のmutexは、スキップの問題を解決しない。

このため、私はもう何を考えているのかわかりません、ソケットからの文字列は正しく来るのです。
が文字列型 wchar_t* を受け取った場合、それは自動的に Unicode 符号化され、文字列中の各文字は 2 バイトに相当することを意味します(テスト済み)。
しかし、どういうわけか、wchar_t*ポインタが12バイトの文字列に8バイトを正しくコピーすることが理解できないのです。
OSのビットペリフェラルサイズが何か他の影響を及ぼしているのでは?64bit版、Windows、Linuxで全て確認済みです。

 

よくわからないのですが、隙間や空白の線は何ですか?

すべてのスレッドから同じMQLラインに書き込むのか、それとも別々のスレッドに書き込むのか?

MQLのコードでは、いつ文字列にデータがあり、処理/出力できると判断するのでしょうか?


もし、すべてが1行に収まっているのが間違いであれば、DLL側にMQLからアクセスできるクリティカルセクションが必要で、行変更カウンタ


MQLの疑似コード

#import ...
   bool LockValueIfChanged();
   void UnlockValue();
#import


while(!_IsStopped())
  {
   if(LockValueIfChanged())
     {
      Print( Value );
      UnlockValue();
     }
  }

DLL

uint64_t last_mql_counter=0;
uint64_t counter=0;

bool LockValueIfChanged()
  {
   Lock(cs);

   if(last_mql_counter!=counter)
    {
     last_mql_counter=counter;
     return(true);
    }

   Unlock(cs);
   return(false);
  }

void UnlockValue()
  {
   Unlock(cs);
  }

Thread()
  {
   while( running )
     {
      Lock(cs);

      Value = ...

      counter++;

      Unlock(cs);
     }
  }


これはスキームの例であり、MQL側からは行をスキップすることになります(すべての行がMQLに届くわけではなく、一部は上書きされます)。

 
Ilyas:

よくわからないのですが、隙間や空白の線は何ですか?

すべてのスレッドから同じMQLラインに書き込むのか、それとも別々のスレッドに書き込むのか?

MQLのコードでは、いつ文字列にデータがあり、処理/出力できると判断するのでしょうか?


もし、すべてが1行に収まっているのが間違いであれば、DLL側にMQLからアクセスできるクリティカルセクションが必要で、行変更カウンタ


MQLの疑似コード

DLL


これはスキームの例であり、MQL側からは行をスキップすることになります(すべての行がMQLに届くわけではなく、一部は上書きされます)。

はい、空のラインです。スクリーンショットで確認できます。
すべてのスレッドからMQLの1ラインまではい。文字列用の変数をその場で作るのも問題なので。
文字列がどこから来るのか、いくつのソースが絡んでくるのかが事前にわからないと、つまりはダイナミックに。
また、クリティカルセクションについても考えていて、MQLは何らかの方法で読み取りをブロックする必要があるとも考えていました。例題をありがとうございます、よく考えてみます。
しかし、やはり文字列のソースはそれぞれ別の変数で取得することをお勧めすることがわかりましたか?しかも、MQLの1変数ではありません。
ただ、全スレッドからの受信データを1つの文字列変数で扱う方が便利なんです。
dll側で書き込みロックがかかっていれば、MQLでは読み込みはロックを必要としない、つまりMQLがそのようなコピー実装を考慮しているようなものだと考えていました。
しかし、1つのスレッドから文字列を取得しても、スキップが発生するのです
他のコピー関数を正しいパラメータで使用すると、1スレッドでも複数スレッドでもスキップは発生しませんが、不揃いの文字列が発生することに変わりはありません。
間違ったパラメータを使用すると、文字列は均一ですが、漏れ始めます。

ファイル:
458.png  71 kb
 
Ilyas:

少なくてOKなら、通常、文字列バッファは 常に文字列自体よりわずかに大きい(しかし、それは事実ではない!)。

しかし、それ以上書くと、ほぼ間違いなく端末がクラッシュします。
また、クラッシュはすぐには発生せず、次の動的メモリ操作(配列や文字列バッファの再分配)やシャットダウン時(MQLプログラムの使用済みメモリがシステムに戻される時)にのみ発生する可能性が高いです。

では、なぜ新参者にwcscpy 関数を使うように勧めるのですか?

より安全な関数として、wcscpy_s, wmemcpy_s があります。

 

OnCalculate ハンドラで、新しく形成された各バーの時間 time[0] が SymbolInfoTick 関数を使用して要求したティック時間より進んでいる理由を教えてください。SymbolInfoTick関数は、常に最後の既知のティックを返す必要があります。

テスターでこの問題を汗だくモードで再現したインジケータを添付します。

2019.10.12 16:51:53.667 2019.01.02 06:00:00   Time 2019.01.02 06:00:00 = 1546408800000 is ahead of tick:  1546297199572
2019.10.12 16:51:53.753 2019.01.02 06:01:00   Time 2019.01.02 06:01:00 = 1546408860000 is ahead of tick:  1546408830000
2019.10.12 16:51:54.315 2019.01.02 06:02:00   Time 2019.01.02 06:02:00 = 1546408920000 is ahead of tick:  1546408919000
2019.10.12 16:51:54.617 2019.01.02 06:03:00   Time 2019.01.02 06:03:00 = 1546408980000 is ahead of tick:  1546408979000

各バーバウンドでは、このような問題があります。

PS.また、ドキュメントによると、OnCalculateはすべてのティックに対して漏れなく呼ばれるとのことなので、ティックボリュームは常にティックカウンターと一致するはずですが、必ずしもそうではありません。
ファイル:
fake.mq5  2 kb
 
Stanislav Korotky:

OnCalculateハンドラで、新しく形成された各バーの時間が、SymbolInfoTick関数で要求しているティック時間より進んでいるのはなぜですか?SymbolInfoTick関数は、常に最後の既知のティックを返す必要があります。

テスターでこの問題を汗だくモードで再現したインジケータを添付します。

各バーバウンドには、この問題があります。

PS.また、このインディケータはもう一つの問題を示しています。ティックカウントがあり、OnCalculateが欠けることなくすべてのティックに対して呼び出されるというドキュメントの記述から判断すると、ティックのボリュームは常にティックカウンターと一致するはずですが、これは常にそうではありません。

ビルドナンバーを教えてください。

 
Slava:

ビルド番号を教えてください

2093

 
Stanislav Korotky:

2093

ご指摘の問題は、ビルド2155で修正されました。

 

エディターでハイライトされた定数SYMBOL_CHART_MODE_OLDが 見つかりました。

もちろんENUM_SYMBOL_CHART_MODEには ありません。

何ですか?

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Для получения текущей рыночной информации служат функции SymbolInfoInteger(), SymbolInfoDouble() и SymbolInfoString(). В качестве второго параметра этих функций допустимо передавать один из идентификаторов из перечислений ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING соответственно. Некоторые символы (как...