Перейти к содержанию
    

Создал строку:

char *Buff = "Hello, ViKo!\r\n";

Передаю раз в секунду через CDC в STM32F3Discovery:

CDC_Transmit_FS((uint8_t *)Buff, sizeof Buff);

Получаю в терминальной программе:

HellHellHellHell...

 

Передаю иначе:

CDC_Transmit_FS((uint8_t *)Buff, sizeof *Buff);

Получаю:

HHHH...

 

Что же, компилятор не знает длину строки, что хранит в своих таблицах?

 

P.S. Естественно, когда пишу

CDC_Transmit_FS((uint8_t *)Buff, 14);

то все нормально.

 

P.P.S. и скобками аргумент для sizeof обкладывал, не помогло.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поищите в вашей версии Си функцию типа strlen.

Использовать функцию sizeof для строки некорректно, она для другого предназначена.

 

ЗЫ. Посмотрите в отладчике, ваша строка, размещенная в памяти, нулем завершается? Все функции вычисления длины строки ищут окончание в виде нулевого байта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поищите в вашей версии Си функцию типа strlen.

Использовать функцию sizeof для строки некорректно, она для другого предназначена.

 

ЗЫ. Посмотрите в отладчике, ваша строка, размещенная в памяти, нулем завершается? Все функции вычисления длины строки ищут окончание в виде нулевого байта.

Нулем завершается, конечно.

Написал по-простому:

char Buff[] = "Hello, ViKo!\r\n";

CDC_Transmit_FS((uint8_t *)Buff, sizeof Buff);

Все передается, и нуль тоже.

Hello, ViKo!<\r><\n><\0>

 

Мне непонятно, sizeof указателя должен же быть равен 4 для Cortex. Почему один символ передается?

Так нормально работает, спасибо!

char *Buff = "Hello, ViKo!\r\n";

CDC_Transmit_FS((uint8_t *)Buff, strlen (Buff));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же, компилятор не знает длину строки, что хранит в своих таблицах?

 

А в чем проблема-то ? Читайте Кернигана с Ритчи и голова болеть не будет. Там все написано.

 

-- объявление указателя на инициализированный участок памяти

char* Buf = "abc";

 

sizeof(Buf) - это размер указателя на строку, в вашем случае, похоже, 4 байта.

sizeof(*Buf) - размер типа данных, на который этот указатель указывает, то есть char, в вашем сулчае 1 байт.

 

-- объявление _массива_

char Arr1[] = "asdf";

sizeof(Arr1) == sizeof(char)*_5_;

 

int Arr2[] = {1,2,3};

sizeof(Arr2) == sizeof(int)*3;

 

Длинна строки не обязательно должна быть равна длинне массива.

const char Str1 = "abcd\0asdf";

Длинна строки Str1 будет 4 символа.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне непонятно, sizeof указателя должен же быть равен 4 для Cortex. Почему один символ передается?

Все правильно, для первого примера:

sizeof(Buff) возвращает размер указателя на char

sizeof(*Buff) возвращает размер char

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О, спасибо! Действительно, все оказалось просто, когда рассказали.

А длину строки, на которую указывает указатель, только с помощью strlen вычислять?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А длину строки, на которую указывает указатель, только с помощью strlen вычислять?

Только так (или руками).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однако, sizeof вычисляется на этапе компиляции (обычно), а strlen нет.

 

Можно подставить макроопределение вместо строки.

#define STR_HI_ALL "Hi, All!"

char *Buff = STR_HI_ALL;

CDC_Transmit_FS((uint8_t *)Buff, sizeof(STR_HI_ALL));

Результат не проверял. Дома не на чем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно подставить макроопределение вместо строки.

#define STR_HI_ALL "Hi, All!"

char *Buff = STR_HI_ALL;

CDC_Transmit_FS((uint8_t *)Buff, sizeof(STR_HI_ALL));

Результат не проверял. Дома не на чем.

 

На кой? Чтоб запутать потенциального противника ?

 

Было же уже решение для вашего (непонятно зачем) случая:

const char szStr[] ="abcd";

 

Кстати, функция

CDC_Transmit_FS() объявлена коряво. По-хорошему, ее надо сделать такой:

 

void CDC_Transmit_FS(const void* apData, uint8_t aNumBytes);

 

Тогда не надо будет кастить первый аргумено при ее вызове с любым типом данных

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На кой? Чтоб запутать потенциального противника ?

Да, это уже не имеет смысла.

Кстати, функция

CDC_Transmit_FS() объявлена коряво. По-хорошему, ее надо сделать такой:

void CDC_Transmit_FS(const void* apData, uint8_t aNumBytes);

Тогда не надо будет кастить первый аргумено при ее вызове с любым типом данных

Это камень в бошки программистов STM32Cube. :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А длину строки, на которую указывает указатель, только с помощью strlen вычислять?

 

Если строка не меняется между вызовами, то через sizeof(Buff) - 1

 

const uint8_t Buff[] = "Hello, ViKo!\r\n";
CDC_Transmit_FS(Buff, sizeof(Buff) - 1);

 

Это камень в бошки программистов STM32Cube

 

Не вдаваясь в подробности реализации CDC_Transmit_FS внутри функции указатель типа uint8_t * проще инкрементировать или обращаться к произвольному элементу по индексу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не вдаваясь в подробности реализации CDC_Transmit_FS внутри функции указатель типа uint8_t * проще инкрементировать или обращаться к произвольному элементу по индексу.
Действия внутри функции - личное дело ее создателя. Никто и ничто не мешает ему создать локальную копию переданного указателя любого нужного типа. Поскольку функция может передавать что угодно, она должна получать "указатель на константное что угодно", т.е. void const *. В качестве примера можно посмотреть на memcpy() и подобные функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сергей, я Вас безмерно уважаю, но то что, так сделано в функции memcpy - это ни разу не аргумент. Функция CDC_Transmit_FS передает данные во внешний мир и передавать в нее что угодно как минимум не всегда корректно в плане переносимости между платформами из-за порядка байт и выравнивания структур.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция CDC_Transmit_FS передает данные
Вот именно, что данные. Которые совсем не обязательно будут массивом байтов. Поэтому возлагать на пользователя необходимость захламлять исходник явными приведениями типа указателя на эти данные к указателю на массив байтов по меньшей мере непрофессионально. Кроме всего прочего параметр должен быть указателем именно на константные данные, потому что функция эти данные не меняет, значит а) может работать и с константными данными (из флеша) и б) константность помогает компилятору сгенерить более оптимальный код.

 

Все это вопросы хорошего стиля и подобные ляпы в примерах от производителя чести этому производителю не делают.

 

сравните:

 

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
....
}

void test()
{
    static char const Hello_string[] = "Слава мне, победителю драконов!";

    CDC_Transmit_FS((uint8_t*)Hello_string, sizeof(Hello_string) - 1);
}

и

uint8_t CDC_Transmit_FS(void const * psrc, uint16_t Len)
{
     uint8_t const * Buf = (uint8_t const *)psrc;
....
}

void test()
{
    static char const Hello_string[] = "Слава мне, победителю драконов!";

    CDC_Transmit_FS(Hello_string, sizeof(Hello_string) - 1);
}

одна строка в исходнике библиотечной функции разгружает от мусора исходник приложения и позволяет сосредоточится на решении задачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однако, sizeof вычисляется на этапе компиляции (обычно), а strlen нет.
Зависит от компилятора.

Например GCC благодаря Built-in Functions умеет считать длину константной строки на этапе компиляции даже при использовании strlen.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...