Используя SDK для Symbian S60 5th edition, выпущенный 2 октября, я компилирую / запускаю (на SIM-карте) следующий фрагмент кода:
void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
va_list vl;
va_start(vl, fmt);
vswprintf(dest, size, fmt, vl);
va_end(vl);
}
...
wchar_t str[1024];
// this crashes (2nd string 123 characters (+ \0) equals 248 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a tes");
// this works (2nd string 122 characters (+ \0) equals 246 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a te");
По не очевидной для меня причине (даже после того, как я прочитал справочную страницу vswprintf сто раз), могу ли я понять, почему этот код вылетает у меня при вызове vswprintf для длинных строк :-( Тот же самый код отлично работает в Linux-системе . Для str выделено достаточно памяти, плюс vswprintf все равно проверяет переполнение буфера. К сожалению, отладчик ... S60 не ломается при этом сбое, поэтому подробностей у меня нет :-(
У кого-нибудь есть идеи?
Если допустить ошибку в подпрограмме vswprintf Symbian, какие функции можно заменить с использованием POSIX-совместимого кода? (предполагается, что это кроссплатформенная библиотека)
Спасибо.





Измените% S на% s - верхний регистр на нижний.
В printfs на основе MS% S означает символы Юникода, поэтому строка из 123 символов не работает, она ожидает 2 байта на символ. (обратите внимание:% S не является частью стандарта, поэтому Symbian здесь может быть другим)
Собственно, я думаю, что это все еще относится к Symbian.
Адам прав, в стандарте написано% s = char *,% S = wchar_t *. MS облажалась, сделав% s TCHAR и% S! TCHAR, отсюда и путаница. % S здесь действительно прав. Даже если бы это было не так, это не привело бы к сбою (просто строка должна состоять только из одного символа).
Для меня это похоже на работу по вызову vswprintf(). Даже если вы можете выполнять отладку только на уровне сборки, должно быть ясно, что более или менее происходит, следя за тем, что происходит в памяти str[].
Вы можете попробовать изменить спецификатор формата %S на %ls. Как упоминалось в моем предыдущем комментарии, они должны быть эквивалентными, но в реализации может быть ошибка. Обратите внимание, что функция vswprintf определена в стандарте C99, и, поскольку еще нет полностью соответствующих компиляторов C99 (я считаю), вполне возможно, что любая конкретная реализация vswprintf не полностью соответствует спецификации или содержит ошибки. (первое более вероятно, чем второе).
В документации по Symbian (см. Соответствующую ссылку) действительно упоминается% S. Тем не менее попробовать стоит ... к сожалению, это нисколько не меняет ситуации.
Можете ли вы попробовать не вызывать test () и вместо этого использовать swprintf - в случае, если ошибка связана с обработкой VARARGS?
Использование swprintf не имеет значения.
Теперь я "решил" эту проблему, используя функции Symbian для выполнения этой задачи:
void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
VA_LIST args;
VA_START(args, fmt);
TPtrC16 fmtPtr((const TUint16*)fmt, wcslen(fmt) + 1);
TPtr16 targetPtr((TUint16*)dest, size);
targetPtr.FormatList(fmtPtr, args);
targetPtr.ZeroTerminate();
VA_END(args);
}
(в этом случае вам действительно нужно используйте% s)
Мне довелось найти внутренний буфер внутри реализации vswprintf, который жестко закодирован до 128 байт. Это вполне могло вызвать такой сбой на длинных струнах.
Нет, он хочет% S (что эквивалентно% ls) - префикс L перед строковыми константами делает их строковыми константами расширенных символов.