Hatalar, hatalar, sorular - sayfa 2575

 
Roman :

Bellek, mql kodunda şu şekilde tahsis edilir:

mql'deki dize, dll'deki wichar_t* olduğundan, dışarı çıkar ve tahsis edilen belleğe bir işaretçi olarak iletilir.

Ah nasıl gidiyor...

Dize uygulamasını bilmiyorum, yalnızca tahmin edebilirim, ancak hataya bakılırsa, dize çıktığında, yığında 0x00000000 olarak başlatılan bir işaretçi oluşturulur ve dll'deki boş işaretçiyi güvenle kaldırırsınız.

 
Vladimir Simakov :

Ah nasıl gidiyor...

Dize uygulamasını bilmiyorum, yalnızca tahmin edebilirim, ancak hataya bakılırsa, dize çıktığında, yığında 0x00000000 olarak başlatılan bir işaretçi oluşturulur ve dll'deki boş işaretçiyi güvenle kaldırırsınız.

Üzgünüm, StringInit fark etmedi(((
 
Roman :

Bellek, mql kodunda şu şekilde tahsis edilir:

mql'deki dize, dll'deki wchar_t* olduğundan, dışarı çıkar ve tahsis edilen belleğe bir işaretçi olarak iletilir

Dll'nin kendisini kazın, büyük olasılıkla orada bir şey var. Son zamanlarda verileri mql'den üçüncü taraf C++/C# uygulamalarına aktarıyorum, hiç sorun yaşamadım.

 
Vladimir Simakov :

Dll'nin kendisini kazın, büyük olasılıkla orada bir şey var. Son zamanlarda verileri mql'den üçüncü taraf C++/C# uygulamalarına aktarıyorum, hiç sorun yaşamadım.

Dll'de her şey basittir, netlik için gereksizler kaldırılır, fikrin kendisi gösterilir

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

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

Sonuç verilerini konsola aktarıyorum, konsoldaki tüm satırlar net bir şekilde boşluklar ve aksaklıklar olmadan gidiyor.
wcscpy(out, data) ile mql'ye iletiyorum sorun başlıyor
Ve elle yazılmış bir test dizisini geçersem

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

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

Neden sorun yok.

Hmm, mql'deki dize türü , wchar_t*'ın terminal sıfırını hesaba katıyor mu?

 

OnTimer() olay yeteneğinin küçük bir uzantısı için öneri

Şu anda OnTimer() olayı, çağrı frekansının EventSetTimer() işlevi tarafından ayarlandığı andan itibaren oluşmaya başlar.

İşte böyle bir danışman olduğu ortaya çıktı:

 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);
}
//+------------------------------------------------------------------+

Böyle bir şey verir:

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

Bununla birlikte, genellikle, bir sinyalin oluşumunu kontrol etmek için, bir sonraki çubuğun ortaya çıkmasından sonra kontrol etmek yeterlidir.

Ve örneğin, PERIOD_M15 için çubuğun 00:15:00'da görüneceği ve EA'nın yalnızca 00:29:59'da kontrol edebileceği ortaya çıktı.

Onlar. danışmanın başlama saatinden bağımsız olarak az çok istikrarlı ve aynı sonuçlar için,

daha kısa süreler için bir zamanlayıcı ayarlamanız veya ek olarak OnTick() kullanmanız gerekecektir.

Deneyler, bunun strateji test cihazındaki test hızını büyük ölçüde yavaşlattığını göstermiştir.

Teklif:

OnTimer olayının gerçekleşmesi için geri sayımın başlangıç zamanını ayarlamanıza izin verecek bir işlev ekleyin.

Örneğin, yeni bir çubuktan birkaç saniye sonra zamanlayıcı çağrısını ayarlamanıza izin veren bazı EventSetTimerFrom (const datetime SinceDT) işlevi .

 
Roman :

Dll'de her şey basittir, netlik için gereksizler kaldırılır, fikrin kendisi gösterilir

Sonuç verilerini konsola aktarıyorum, konsoldaki tüm satırlar net bir şekilde boşluklar ve aksaklıklar olmadan gidiyor.
wcscpy(out, data) ile mql'ye iletiyorum sorun başlıyor
Ve elle yazılmış bir test dizisini geçersem

Neden sorun yok.

Hmm, mql'deki dize türü , wchar_t*'ın terminal sıfırını hesaba katıyor mu?

Ve bu fonksiyon çalışıyor

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

Ancak eğri, satırın sonunda bir karakter eksik gibi görünüyor, fazladan bir parantez } beliriyor ve sonra kayboluyor.
wcslen(veri)+1
wcslen(veri)+2
Yardım etmedi,
ve sözde herhangi bir sızıntı olmadan hatasız olarak ayrıştırılır

bir mql dizesindeki bir karakterin uzunluğunun veya boyutunun ne olduğu hiç belli değil
dize türünde kesinlikle bir tür hata var

Ve paragraf 3.3'teki en son makalede Dizeleri aktarma ve değiştirme, örnek büyük olasılıkla bir hata yaptı.

_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 * )
  }

Belki de, uçbirim kodunun bir yerinde, mql dize dönüştürmesi, bir işaretçi olmadan aynı şekilde çalışır.

 
Maksim Emeliashin :

OnTimer olayının gerçekleşmesi için geri sayımın başlayacağı başlangıç zamanını ayarlayın.

EventSetTimer'ı tekrar arayarak kendiniz yapabilirsiniz. Hesapta (Test Cihazında değil) zamanlayıcının değişken olduğunu ve sürekli ayarlama gerektirdiğini unutmayın.

 
fxsaber :

EventSetTimer'ı tekrar arayarak kendiniz yapabilirsiniz. Hesapta (Test Cihazında değil) zamanlayıcının değişken olduğunu ve sürekli ayarlama gerektirdiğini unutmayın.

Teşekkürler, faydalı şeyler!

Bu kadar basit bir anın kutudan çıkan terminalde dikkate alınmaması elbette çok garip.

 
Roman :

Ve bu fonksiyon çalışıyor

Ancak eğri, satırın sonunda bir karakter eksik gibi görünüyor, fazladan bir parantez } beliriyor ve sonra kayboluyor.
wcslen(veri)+1
wcslen(veri)+2
Yardım etmedi,
ve sözde herhangi bir sızıntı olmadan hatasız olarak ayrıştırıldı

bir mql dizesindeki bir karakterin uzunluğunun veya boyutunun ne olduğu hiç belli değil
dize türünde kesinlikle bir tür hata var

Ve paragraf 3.3'teki en son makalede Dizeleri aktarma ve değiştirme, örnek büyük olasılıkla bir hata yaptı.

Belki de, uçbirim kodunun bir yerinde, mql dize dönüştürmesi, bir işaretçi olmadan aynı şekilde çalışır.

getData() kazı. Bana öyle geliyor ki bir yerlerde bir pusu var.
 
Roman :

Dll'de her şey basittir, netlik için gereksizler kaldırılır, fikrin kendisi gösterilir

Çok güzel örnekleriniz var, her şeyi kaldırdılar, UB'yi bıraktılar (dize değişmezlerinin değiştirilmesi) ve herkes telepati yapmalı. Bir tür mantıklı tavsiyeye güveniyorsanız, minimum çalışma kodunu (her iki tarafta da) verin, aksi takdirde sadece gevezelik olur.