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

 
Roman:

として、mqlのコード内でメモリが確保されます。

mqlの文字列はDLLのwichar_t*であるため,割り当てられたメモリへの ポインタとして渡されます。

ああ、なんてメチャクチャなんだろう...。

文字列の実装を知らないので推測するしかありませんが、エラーから判断すると、string outはスタック上に0x00000000に初期化されたポインタを作成し、安全にDLLのNULLポインタをデリファレンスしていますね。

 
Vladimir Simakov:

ああ、複雑だなあ...。

文字列の実装を知らないので推測するしかありませんが、エラーから判断すると、string outはスタック上に0x00000000に初期化されたポインタを作成し、安全にDLLのNULLポインタをデリファレンスしていますね。

すみません、StringInit(((;゚Д゚)))ガクガクブルブル
 
Roman:

として、mqlのコード内でメモリが確保されます。

mqlの文字列がDLLのwchar_t*と同じように,割り当てられたメモリへの ポインタとして渡されます。

DELLそのものを掘り下げると、そこに何かがある可能性が高い。最近、私はmqlからサードパーティのC++/C#アプリケーションにデータを供給していますが、全く問題はありません。

 
Vladimir Simakov:

DELLそのものを掘り下げると、そこに何かあるはずです。最近、私はmqlからサードパーティのC++/C#アプリケーションにデータを供給していますが、全く問題はありません。

dllはシンプルで、わかりやすくするために必要なものではなく、アイデアそのものが示されています。

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = getData();  //getData библиотечная функция возвращает const wchar_t*
   wcscpy(out, data);
}

結果データをコンソールに出力すると、コンソールのすべての行がクリアで、ギャップや不具合はありません。
wcscpy(out, data)を通してmqlに結果を渡すのですが、今度は問題が発生しました。
しかし、手書きで書いたチェック文字列を渡すと

wchar_t* out        = L"";
const wchar_t* data = L"";

while(condition)
{
   data = L"{\"p\":\"2000\"}";  //проверочная строка
   wcscpy(out, data);
}

なぜか問題が起きない。

mqlの文字列型は、端末のnull wchar_t *を考慮するのでしょうか?

ファイル:
 

OnTimer()イベントの可能性を少し拡大する提案

EventSetTimer()関数で呼び出しの周期を設定した時点で、OnTimer()イベントが発生し始める。

以下のExpert Advisorが判明しました。

bool timer_set = false;
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
   if (!timer_set)
      {
         // -- имитация включения советника в какое-то
         // -- случайное время
         string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
         if (TimeCurrent() >= D'2019.09.24 3:47:40')
            {
               EventSetTimer(600);
               timer_set = true;
            }
      }
}
//+------------------------------------------------------------------+
void OnTimer()
{
//---
   string time = TimeToString(TimeTradeServer(), TIME_DATE | TIME_MINUTES | TIME_SECONDS);
   printf("Current time: %s", time);
}
//+------------------------------------------------------------------+

およそ以下のように出力します。

QJ      0       07:53:10.369    test_timer (GBPUSD_i,D1)        2019.09.24 03:57:41   Current time: 2019.09.24 03:57:41
NF      0       07:53:11.246    test_timer (GBPUSD_i,D1)        2019.09.24 04:07:41   Current time: 2019.09.24 04:07:41

ただし、別のバーが出現した後に信号の発生を確認すれば十分な場合が多い。

例えば、PERIOD_M15の場合、00:15:00にバーが表示されますが、Expert Advisorによるチェックでは00:29:59にしかチェックできないことが判明しました。

つまり、Expert Advisorの起動時間に関係なく、多かれ少なかれ安定した均等な結果を得ることができるのです。

の場合、タイマーをもっと短い時間に設定するか、OnTick()を追加で使用する必要があります。

実験が示すように、ストラテジーテスターでのテスト速度が劇的に遅くなる。

提案します。

OnTimerイベントのカウントを開始する初期時刻を設定できる機能を追加する。

例えば、ある関数EventSetTimerFrom(const datetime SinceDT)は、新しいバーから数秒後にタイマーを呼び出すように設定することができるようになります。

 
Roman:

dllはシンプルで、わかりやすくするために余計なものは削除し、アイデアを示しています。

結果をコンソールに貼り付けると、すべての行がOKで、ギャップも不具合もない。
wcscpy(out, data) を通してmqlに結果を渡すのですが、今度は問題が発生しました。
しかし、手書きで書いたチェック文字列を渡すと

なぜか問題が起きない。

mqlの文字列型は、端末のnull wchar_t *を考慮するのでしょうか?

しかし、この機能は有効です。

wcsncpy(out, data, wcslen(data));

しかし、どうもおかしい。文字列の最後に1つだけ悪い文字があるようで、余分なブラケット } が現れては消えている。
wcslen(データ)+1
wcslen(データ)+2
は役に立たなかった。
で、エラーもなく、漏れもなくパースされます。

mqlルック文字列の1文字の長さや大きさがわからない。
は、確かに文字列の型に誤りがあります。

そして、ずっと前の記事で 3.3項の文字列の受け渡しと変更で、最も間違えやすい例になっています。

_DLLAPI void fnReplaceString(wchar_t *text, wchar_t *from, wchar_t *to)
  {
   wchar_t *cp;
    
   //проверка параметров
   if(text==NULL || from==NULL || to==NULL) return;
   if(wcslen(from)!=wcslen(to))             return;
   
   //поищем подстроку
   if((cp=wcsstr(text,from))==NULL)         return;
   
   //заменим
   memcpy(cp,to,wcslen(to)*sizeof(wchar_t));  //в этой строке должен быть указатель sizeof(wchar_t *)
  }

おそらく、ターミナルのコードのどこかで、mqlの文字列変換がポインタなしで、同じように動作しているのでしょう。

 
Maksim Emeliashin:

OnTimer イベントのカウントダウンを開始する初期時刻を設定する。

これは、EventSetTimerを繰り返し呼び出すことで、自分で行うことができます。アカウントでは(テスターではなく)タイマーが浮き、常に調整が 必要であることに注意してください。

 
fxsaber:

これは、EventSetTimerを繰り返し呼び出すことで、自分で行うことができます。アカウント(テスターではありません)では、タイマーが浮いているため、常に調整が 必要であることに留意してください。

ありがとうございます!便利なものですね。

もちろん、このような単純な点が「箱から出して」端末に考慮されていないのは非常に不思議なことです。

 
Roman:

しかし、この機能は有効です。

しかし、文字列の最後に余分な括弧 } が出たり消えたりして、ちょっと不便なようです。
wcslen(データ)+1
wcslen(データ)+2
は役に立たなかった。
で、エラーもなく、漏れもなくパースされます。

mqlルック文字列の1文字の長さや大きさがわからない。
は、確かに文字列の型に誤りがあります。

そして、ずっと前の記事で 3.3項の文字列の受け渡しと変更で、最も間違えやすい例になっています。

おそらく、ターミナルのコードのどこかで、mqlの文字列変換が、ポインタなしで、同じように動作しているのでしょう。

getData() dig.どこかに問題があるような気がするんです。
削除済み  
Roman:

dllはシンプルで、わかりやすくするために削除され、アイデアが示されている

あなたの例はおかしい、あなたはすべてを削除し、UB(文字列リテラルの修正)を残し、誰もがテレパシーをしなければならないのです。賢いアドバイスを期待するならば、最小限の動作するコード(2面)を与えなさい、さもなければただのゴミです。