Ошибки, баги, вопросы - страница 2576
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Прикольные такие примеры у вас, всё убрали, оставили UB (модификация строковых литералов), а все телепатить должны. Если рассчитывайте на какой-то толковый совет, то приведите минимальный рабочий код (на двух сторонах), иначе просто трёп.
В примере показано то место которое вызывает проблему, то есть проблема в копировании указателя wchar_t* в mql-овкий string.
Остальной код не относящийся к проблеме, не несёт полезной нагрузки, так как всего лишь выполняет проверку if данные есть, тогда читаем, и т.д.
Зачем его писать в пример и засорять саму суть проблемы, когда даже с упрощённым кодом многие не поймут в чём суть проблемы.
Поймите getData() сетевая функция, которая читает FrameOpcode, и возвращает полученные данные в виде указателя на строку типа const wchar_t*.
Всем известно что простая функция wcscpy(out, data) копирует const wchar_t* строку, в строку wchar_t*, и автоматически считает длину символов до терминального нуля const wchar_t*
Вот тут то и проявляется ошибка, mql-овский string не корректно принимает скопированную строку wchar_t*, вопрос почему такое может быть? Если функция автоматически определяет терминальный ноль.
В статье Рената строки копируются через memcpy с допущенной ошибкой по размеру байтов. Возможно такой же подход используется в самом коде терминала, для формирования mql-овского типа string.
Понимаете, memcpy не только не подходит для копирования строк, так ещё и с ошибкой в размере переданных байт, приводит к неровным данным.
Для копирования строк ведь есть другие специальные для этого Сишные функции, такие как wcscpy, wcsncpy и т.д.
Да и сам Ренат в одной из веток писал, что вскоре будут полностью перерабатывать работу со строками, видимо проблема известна, но почему то тишина в ответ на обозначенную мной проблему.
Вот для сравнения размер байт указателя wchar_t*, и простого типа wchar_t
Кончено, проще написать целую портянку в ответ, чем нормальный воспроизводимый тест заменив getData() на что-то. Чего ожидаете, если UB на UB, и выводы неверны:
всё там правильно. Что-то не так с вашими представлениями о строках, отсюда и обшибки.
Кончено, проще написать целую портянку в ответ, чем нормальный воспроизводимый тест заменив getData() на что-то. Чего ожидаете, если UB на UB, и выводы неверны:
всё там правильно. Что-то не так с вашими представлениями о строках, отсюда и ошибки.
Воспроизводимый код предоставить нет возможности, так как сами понимаете что это dll, использующая сторонние библиотеки.
По поводу почему я решил что в примере ошибка.
memcpy(cp,to,wcslen(to)*sizeof(wchar_t)); //в этой строке должен быть указатель sizeof(wchar_t *)
Используя функцию без указателя,
то конец строки начинает плыть лишними символами. Посмотрите на конец строки на снимке.
Да и логично же, что если мы копируем строку wchar_t* как указатель, то и нужно передавать размер указателя, а не размер типа.
А если использую указатель,
то строка чёткая, без лишних символов.
Всё бы не чего, да вот в обоих случаях почему то возникает дальнейшая проблема с парсингом, то течь строк, то пропуски.
А если использую вот эту функцию,то не чего не течёт, всё парсится хорошо, только один лишний символ в конце строки бажит, то появляется то исчезает.
Вот и перебираю кучу вариантов где может быть причина, но используя memcpy без указателя в sizeof, результат виден на скрине.
Хочу ещё проверить полученную wchar_t* строку на терминальный ноль, есть он или нет.
Как это можно сделать?
тут out останется без \0 в конце
А если использую указатель,
тут вы выходите за границы out
опять out останется без \0. Смотрите доки
wcsncpy, wcsncpy_s
...If countis reached before the entire string srcwas copied, the resulting wide character array is not null-terminated.
...
ЗЫ: может не связываться со строками вообще? сохраняйте в wchar_t массивы и гоняйте их, а внутри мкл конвертировать в строку если надо https://www.mql5.com/ru/docs/convert/shortarraytostring
ЗЫ: может не связываться со строками вообще? сохраняйте в wchar_t массивы и гоняйте их, а внутри мкл конвертировать в строку если надо
О, сенкю )), за подсказку, что wcsncpy обрезает ноль.
Да массивы оставил на последок, если не получится с указателями, то буду юзать массивы.
Движок форума не позволяет сделать пост из одной картинки. Требует ввода текста.
Приходится ставить пробел.
Движок форума не позволяет сделать пост из одной картинки. Требует ввода текста.
Приходится ставить пробел.
Вроде всё логично: это форум и главное это текст. А картинка прикладывается по сколько постольку. Здесь ведь не кладбище картинок.
дописал код, работает в MT4/5, столкнулся небольшой неожиданностью
а чем в MQL4 можно заменить TesterStop()
?
а чем в MQL4 можно заменить TesterStop()?
ExpertRemove.
ExpertRemove.
этот вариант знаю, но видел сообщения, что ExpertRemove(0 нельзя для экспертов для Маркета использовать, может соберусь в Маркет выложить, придется опять переделывать
в общем использую TesterStop() в двух случаях:
- вместо INIT_PARAMETERS_INCORRECT , чтобы скрыть лог оптимизатора
- если недостаточно средств для открытия ордера, ордер то не открываю, а тест завершаю, что оптимизация быстрее шла