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

[Удален]  
Roman:


Нет, так не сработало, строка не передается, но и проблем не возникает.
А вот так без нуля сработало, но так плывёт конец строки лишними символами.

Если не сработало, значит на вход подавалась пустая строка. Вариант мой правильный и рабочий, ваш нет.

#include <cstring>
#include <iostream>
using namespace std;

int main() {
        wchar_t out[200];
        wchar_t data[] = L"Hello world";
        memcpy(out, data, wcslen(data)*sizeof(wchar_t)+sizeof(L'\0'));
        wcout << "string = " << out << endl;
}
// string = Hello world

Вы тупо перезаписывайте буфер с большим запасом, естественно, что захватывается и нужная строка.

 
Vladimir Simakov:

PS. Это С, это хардкор, тут форумы курить не стоит, только серьезные издания и доки, только свои мозги.

Этот хардкор (wcslen(data)+1) я уже пробовал, и сейчас попробовал ваш вариант, строка не копируется вообще.

 
Roman:

Этот хардкор (wcslen(data)+1) я уже пробовал, и сейчас попробовал ваш вариант, строка не копируется вообще.

А что означает второй параметр в функции memspy_s?

 
Vladimir Simakov:

А что означает второй параметр в функции memspy_s?

Попробую угадать

 - длина строки out., только +1 символ, который /000 забыли.

 
Vict:

Если не сработало, значит на вход подавалась пустая строка. Вариант мой правильный и рабочий, ваш нет.

Вы тупо перезаписывайте буфер с большим запасом, естественно, что захватывается и нужная строка.

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

const wchar_t* data = getData();

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

 
Vladimir Simakov:
Попробую угадать

 - длина строки out., только +1 символ, который /000 забыли.

Если вы имеете ввиду об этом

StringInit(out, 201, 32);

if (memcpy_s(out, 201 * sizeof(wchar_t), data, (wcslen(data) + 1) * sizeof(wchar_t)))

То строка копируется очень редко, и с большими пропусками по времени.
Этот вариант уже пробовался в самом начале, полистайте пару страниц назад, там я скрины выкладывал.

Вот, такое же поведение как на втором скрине, модеры зачем то имена файлов на кракозябры заменили.

Понимаете, даже вот эта функция  wcscpy(out, data);  которая автоматически считает длину строки, вызывает такое же поведение, временной пропуск всей строки.

[Удален]  
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