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

 
Roman:

Ну как пустая строка? Когда строка из сокета поступает, в других вариантах хоть и кривая, но она не пустая.
Я не говорю что ваш вариант не правильный, но в вашем варианте вы используете массив строки.
В моём случае  это указатель

Сокетная функция возвращает указатель на const wchar_t*
По этому я и грешу на mql баг, потому что уже какие только сишные функции не пробовал, хардкоры с +1 или +2 применял.
Не идёт и всё.

Пишите строки после memcpy() параллельно в файл, если мкл виноват (там ведь какая-то обёртка поверх вызовов с копированием аргументов), то файл не пустой будет, наверное.

ЗЫ: ну так, на всякий случай - в мкл библиотечная функция задекларирована ведь с сылкой ? void fn(string &s)?
 
Vict:

Пишите строки после memcpy() параллельно в файл, если мкл виноват (там ведь какая-то обёртка поверх вызовов с копированием аргументов), то файл не пустой будет, наверное.

ЗЫ: ну так, на всякий случай - в мкл библиотечная функция задекларирована ведь с сылкой ? void fn(string &s)?

Все строки я вывожу или на график в коммент, или в принт терминала, когда строка поступает её сразу видно, в комменте видно кривая она или нет.
Когда идут большие временные пропуски, то строка на графике редко появляется, а в принте дыры.
Сомнение что не поступает строка из сокета отпадает, тиковые данные поступают с частотой в миллисекунды.
Из сокета getData() приняли в переменную указатель, из переменной указателя  сразу копирую в mql, не каких обёрток.
Да задекларирована по феншую ))

#import "ExampleDll.dll"
   void Func(string task, string & out);
#import
В общем по любому траблы с mql-овским string. Испробовано уже и проверено много вариантов.
Строка из сокета идёт с терминальным нулём, и самая достоверная проверочная функция 
wcscpy(out, data);
или
wcsncpy(out, data, wcslen(data));  //wcslen(data)+1
показывает проблему именно на mql

В общем поюзаю пока с sizeof(wichar_t*) посмотрю на поведение.
Но наверно чтобы обезопаситься от изменений от MQ, наверно действительно напишу строки на массивах.
 
Но наверно чтобы обезопаситься от изменений от MQ, наверно действительно напишу строки на массивах.

Золотые слова. Оно конечно хочется string использовать, но в виду отсутствия стандарта с описанием его реализации и/или поведения при передачи в dll, это чистой воды ub получается. А так, string в short[] и спокойно передаешь массив, единственное, что накладные расходы на создание и копирование массива.

PS. Все-таки, сдается мне, что проблема не в mql, а у Вас в либе. У меня все тесты нормально прошли, да и не чему там по логике глючить, string достаточно тривиальная обертка над wchar_t*, а скорее всего над wstring, что бы там напортачить.

 
Vladimir Simakov:

Золотые слова. Оно конечно хочется string использовать, но в виду отсутствия стандарта с описанием его реализации и/или поведения при передачи в dll, это чистой воды ub получается. А так, string в short[] и спокойно передаешь массив, единственное, что накладные расходы на создание и копирование массива.

PS. Все-таки, сдается мне, что проблема не в mql, а у Вас в либе. У меня все тесты нормально прошли, да и не чему там по логике глючить, string достаточно тривиальная обертка над wchar_t*, а скорее всего над wstring, что бы там напортачить.

У меня тоже были сомнения на либу, не чего не исключаю из возможных причин.
Но конвертировал получаемую строку из сокета в ASCII коды, видно что строка корректная.
Дальше идёт простое копирование,
mql не принимает корректно указатель на строку.

Файлы:
1.PNG  32 kb
 
Roman:

Все строки я вывожу или на график в коммент, или в принт терминала, когда строка поступает её сразу видно, в комменте видно кривая она или нет.
Когда идут большие временные пропуски, то строка на графике редко появляется, а в принте дыры.
Сомнение что не поступает строка из сокета отпадает, тиковые данные поступают с частотой в миллисекунды.
Из сокета getData() приняли в переменную указатель, из переменной указателя  сразу копирую в mql, не каких обёрток.
Да задекларирована по феншую ))

В общем по любому траблы с mql-овским string. Испробовано уже и проверено много вариантов.
Строка из сокета идёт с терминальным нулём, и самая достоверная проверочная функция 
показывает проблему именно на mql

В общем поюзаю пока с sizeof(wichar_t*) посмотрю на поведение.
Но наверно чтобы обезопаситься от изменений от MQ, наверно действительно напишу строки на массивах.

Запись в файл - имел в виду на стороне dll, если в файл пишется, а в мкл не попадает, то это уже весомые аргументы с заявлением о баге, может попаравят.

А обёртка есть без вашего желания, MQ скрывают код/адреса от внешнего мира, всё идет не напрямую.

 
Vict:

Запись в файл - имел в виду на стороне dll, если в файл пишется, а в мкл не попадает, то это уже весомые аргументы с заявлением о баге, может поправят.

А обёртка есть без вашего желания, MQ скрывают код/адреса от внешнего мира, всё идет не напрямую.

Записал получаемые строки в файл. 
Так как сокетная функция возвращает указатель на строку, то в файл пишется указатель на строку, и потом этот указатель копируется в mql.
С помощью функции

wcscpy(out,  data);

Длина получаемой строки 164, в mql выделено 200

StringInit(out, 200, 32);

Скопированная строка полученная в mql получается ровная по длине, но идут жёсткие пропуски в копировании.
В скрипте mql цикл while крутится с Sleep(1)

Файлы:
458.PNG  71 kb
 
А если использовать функцию
wcsncpy(out, data, wcslen(data));
Тогда пропусков нет, но скопированные строки получаются не ровные, в конце строки появляются лишние символы.
Добавление wcslen(data)+1 не помогает.

Итог, из всех страниц которые я тут пишу.
mql-овский string не корректно принимает из dll, скопированный указатель на строку const wchar_t*
Файлы:
w6b.PNG  74 kb
qjv2.PNG  73 kb
09i3.PNG  6 kb
 
Roman:

Правильно, я выделяю буфер под строку out, и инициализирую её пробелами.
Далее передаю эту строку(указатель) в dll. 

В dll в out копируются wchar_t* данные, то есть тоже указатель. По логике проблем не должно возникать.
Как я понимаю согласно справке, функция StringInit и должна задавать длину строки.
Но тут ещё с самой функцией StringInit непонятки, указывал длину строки, фигня лезла, указал размер указателя, всё заработало.
Не пойму о какой ручной передаче длины строки вы имели ввиду.

И если использовать sizeof(wchar_t) без указателя, то строка начинает плыть лишними символами, что вызывает проблему с парсингом и утечкой.
Для передачи строк в dll использовался пример Рената, из его статьи как писать dll.
Но вот почему то именно если передаю без указателя sizeof(wchar_t), то строка плывёт, а с указателем sizeof(wchar_t*) проблем нет.
Имне кажется логично, я же копирую строку как указатель, то и размер нужно передавать указателя, а не типа.

Иногда делаешь правильно - не работает.

Делаешь неправильно - кажется, что работает.

В таких случаях надо делать правильно и искать ошибку в другом месте.

 
Roman:

Записал получаемые строки в файл. 
Так как сокетная функция возвращает указатель на строку, то в файл пишется указатель на строку, и потом этот указатель копируется в mql.
С помощью функции

Длина получаемой строки 164, в mql выделено 200

Скопированная строка полученная в mql получается ровная по длине, но идут жёсткие пропуски в копировании.
В скрипте mql цикл while крутится с Sleep(1)

1. В MQL копируется не указатель, а строка.

2. Вы в MQL выделили строку в 200 символов. Потом скопировали в неё 164 символа. После этого, посмотрите размер строки в MQL. Он остался 200.

 
Koldun Zloy:

Иногда делаешь правильно - не работает.

Делаешь неправильно - кажется, что работает.

В таких случаях надо делать правильно и искать ошибку в другом месте.

По этому чтобы было правильно, я отказался от memcpy, и использовал wcscpy или wcsncpy.
Результат, постом выше.

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