Ошибки, баги, вопросы - страница 2707

 
Sergey Dzyublik:

Прошу разработчиков (@Ilyas) обратить внимание на обнаруженный дефект.
Баг МТ5 (build 2377) при выборе подходящей перегруженной функции для аргумента типа указатель более приоритетной становится функция с приведением типа в указатель на родительский класс вместо базового.
Так же отсутствие compile time error, когда указатель на базовый класс присваивается указателю на родительский класс. 

Возможно связанный с данным багом дефект: https://www.mql5.com/ru/forum/1111/page2682#comment_15591437

class A{};
class B : public A{};
class C : public B{};


struct T{
   static void test(A*){
      printf("A*");
   }
   static void test(C*){
      printf("C*");
   }
};

struct TT{
   static void test(B*){
      printf("B*");
   }
};

void OnStart(){
   B b;
   T::test(&b);            // Runtime Error: Incorrect casting of pointers.  Expected result: printf("A*");
   
   A a;
   TT::test(&a);           // Runtime Error: Incorrect casting of pointers.  Expected result: Compilation Error
   B* ptr = &a;            // Runtime Error: Incorrect casting of pointers.  Expected result: Compilation Error
}

Спасибо за сообщение.

Исправлено

Runtime Error: Incorrect casting of pointers.  Expected result: printf("A*");


Остаётся как есть - этот код может получиться в результате специализации шаблона (в части, которая работать не будет, но на компиляцию повлияет).

Runtime Error: Incorrect casting of pointers.  Expected result: Compilation Error
Runtime Error: Incorrect casting of pointers.  Expected result: Compilation Error
 
Roman:

Да действительно в вашем коде, на 80 порт заголовок возвращается, на 443 нет.
Пересмотрел ваш код ещё раз, и не увидел там функцию SocketTlsHandshake.
Ваш код не производит рукопожатия. Возможно в этом дело.
Хотя в справке к этой функции говорится, что она не обязательна, если коннект идёт на 443 порт.

Вот именно, что это не мой код, а из примера разработчиков (у сокетов от MQ - некоторые неинтуитивные особенности, которые выясняются иногда на форуме, поэтому обратился к стандартному примеру). SocketTlsHandshake я пробовал - он у меня всегда во всех условиях возвращает false и не оказывает никакого влияния на решение проблем. Поскольку возвращаются данные сертификата, рукопожатие проходит. Даже заголовок судя по длине приходит, но просто не возвращается в MQL-код. Код ошибки слишком общий, и сам факт ошибки сомнителен. Нужен взгляд изнутри.
 
Stanislav Korotky:
Вот именно, что это не мой код, а из примера разработчиков (у сокетов от MQ - некоторые неинтуитивные особенности, которые выясняются иногда на форуме, поэтому обратился к стандартному примеру). SocketTlsHandshake я пробовал - он у меня всегда во всех условиях возвращает false и не оказывает никакого влияния на решение проблем. Поскольку возвращаются данные сертификата, рукопожатие проходит. Даже заголовок судя по длине приходит, но просто не возвращается в MQL-код. Код ошибки слишком общий, и сам факт ошибки сомнителен. Нужен взгляд изнутри.

Не нужно использовать функцию SocketTlsHandshake, если соединение изначально защищённое ("https://" или порт 443 или 465)

Функция используется в специальных случаях / протоколах

 
Ilyas:

Не нужно использовать функцию SocketTlsHandshake, если соединение изначально защищённое ("https://" или порт 443 или 465)

Функция используется в специальных случаях / протоколах

Я её и не использую. Код для воспроизведения проблемы приложен.

 
Stanislav Korotky:

Я её и не использую. Код для воспроизведения проблемы приложен.

Замените SocketTlsRead на SocketTlsReadAvailable

 
Ilyas:

Замените SocketTlsRead на SocketTlsReadAvailable

А можно поподробнее? В примере документации использована именно SocketTlsRead. Почему там не использовалась SocketTlsReadAvailable?

В каких случаях следует использовать одну функцию, а в каких другую?

Каким образом писать универсальный код для блокирующего чтения из сокета, подходящий и для защищенных и незащищенных соединений - у нас ведь нет аналогичной функции SocketReadAvailable?

PS. Заменил функцию. Ошибка не пропала. Прикладываю обновленный код. GetLastError возвращает 0.

Файлы:
 

В визуальном тестере вызов из индикатора функции CopyTicksRange завершается с ошибкой 4014 (ERR_FUNCTION_NOT_ALLOWED).

Тот же индикатор нормально работает в онлайне на том же инструменте. В чем затык? Запрет на эту функцию в тестере? Не нашел упоминания об этом в справке.

 
Stanislav Korotky:

В визуальном тестере вызов из индикатора функции CopyTicksRange завершается с ошибкой 4014 (ERR_FUNCTION_NOT_ALLOWED).

Тот же индикатор нормально работает в онлайне на том же инструменте. В чем затык? Запрет на эту функцию в тестере? Не нашел упоминания об этом в справке.

Тест по реальным тикам?

 
Stanislav Korotky:
Вот именно, что это не мой код, а из примера разработчиков (у сокетов от MQ - некоторые неинтуитивные особенности, которые выясняются иногда на форуме, поэтому обратился к стандартному примеру). SocketTlsHandshake я пробовал - он у меня всегда во всех условиях возвращает false и не оказывает никакого влияния на решение проблем. Поскольку возвращаются данные сертификата, рукопожатие проходит. Даже заголовок судя по длине приходит, но просто не возвращается в MQL-код. Код ошибки слишком общий, и сам факт ошибки сомнителен. Нужен взгляд изнутри.

Да, я тоже удивился, что без SocketTlsHandshake сертификат возвращается. 
А с функцией SocketTlsHandshake взывает ошибку.
Какая то не явная логика в поведении.

if(SocketConnect(socket, Address, Port, 5000) && SocketTlsHandshake(socket, Address))
Can't connect to echo.websocket.org:443, error 5274

UPD:
Рекомендацию Ильяса увидел.
Да без этой функции, с коннектом проблем нет.
Проблема в чтении.
 
Ilyas:

Замените SocketTlsRead на SocketTlsReadAvailable

Пробовал я так же заменять на SocketTlsReadAvailable

int rsp_len; 

if(ExtTLS)
   rsp_len = SocketTlsReadAvailable(socket, rsp, len); 
   //rsp_len = SocketTlsRead(socket, rsp, len);
else
   rsp_len = SocketRead(socket, rsp, len, timeout);

Поведение тоже самое что и с SocketTlsRead 

UPD:
Эта же проблема есть при использовании SocketTlsHandshake на другой порт.

Причина обращения: