Re: Вопросы по С/С++ (СИ)
Добавлено: Пн июл 13, 2015 20:51:30
Помогите еще разок. Теперь есть массив из uint8_t первый байт младший, второй старший. Как наиболее эффективно сделать массив uitn16_t?
Спасибо!
Спасибо!
Код: Выделить всё
typedef union {
uint8_t arr8[10];
uint16_t arr16[5];
} myType;
int main() {
myType x;
uint16_t a;
x.arr8[0] = 0x34;
x.arr8[1] = 0x57;
a = x.arr16[0]; // a присвоили значение 0x5734;
}Код: Выделить всё
uint8_t source[SIZE]; // исходный массив байтов
uint16_t *dest = (void*)source; // новый массивНе не не. А как же выравнивание адресов? Некоторые архитектуры могут работать только с данными, выровненными по адресу, кратному размеру данных (или большей степени двойки). То есть, чтобы прочитать/записать в int16, это значение должно располагаться в памяти по адресу, кратному хотя бы двум, если нужно прочитать/записать int32, то оно должно располагаться по адресу, кратному хотя бы четырем, и так далее.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
да да даmenzoda писал(а):Не не не.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined. Так что все-равно нужно включать голову и писать переносимый код.ks0 писал(а):это забота компилятора. Сказали второй байт, значит второй байт.
А почему у меня программы не состоят на 90% из аппаратно-зависимых действий? Просто нужно минимизировать и отделять аппаратно-зависимый код от всего остального, и не плодить костыли да хаки там, где это не нужно. А это как раз тот случай, где их можно избежать.ARV писал(а):о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!
я не виноват, что вам не повезло...menzoda писал(а):А почему у меня программы не состоят на 90% из аппаратно-зависимых действий?
Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!menzoda писал(а):Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined.
Код: Выделить всё
#include <avr/io.h>
#include <avr/pgmspace.h>
const char* s PROGMEM = "Text";
void main()
{
char c[20]; // буфер
strcpy_P(c,s);
}
Код: Выделить всё
PROGMEM char str[] = "Что-то там";
sprcpy_P(s, str);Код: Выделить всё
strcpy_P(s, PSTR("Что-то там"));Да нет, с char как раз проблем нет. Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc. В старом стандарте он возвращал как раз char*, который мы приводили к нужному типу. Вот только malloc гарантирует, что возвращенный указатель будет правильно выровнен, поэтому мы и можем смело его приводить к, например, int*.ks0 писал(а): Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!
Если компилятор живёт на платформе с претензиями по выравниванию - то это забота его и его стандартных библиотек чтобы обойти все эти милые особенности как можно более прозрачно для пользователя. И подавляющее большинство последних, вряд-ли задумаются об оптимизации доступа пока конкретные грабли не оходят звонко их незамутнённые лбы. Просто из ваших реплик легко складывается впечатление, что есть ограничения по явному приведению указателей на разные типы. Хотя вряд-ли это так и тип указателя это всего-лишь подсказка компилятору - чтобы знал на сколько двигать при инкременте.menzoda писал(а):Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc.
Код: Выделить всё
devs = hid_enumerate(0x0, 0x0);
cur_dev = devs;
while (cur_dev) {
printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
printf("\n");
printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
printf(" Product: %ls\n", cur_dev->product_string);
printf(" Release: %hx\n", cur_dev->release_number);
printf(" Interface: %d\n", cur_dev->interface_number);
printf("\n");
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);Код: Выделить всё
handle = hid_open(0x1241, 0x1203, NULL);
if (!handle) {
printf("unable to open device\n");
return 1;
}В настройках отладки в Debug Target нужно указывать экзешник а не длл-ку.kalobyte писал(а):когда я пробую запустить отладку, то вылазит сообщение, что не может запустить приложение hidapi.dll
Собрать либку статически а не пару import.lib + dll - ну это при наличии исходного текста, конечно.kalobyte писал(а):а как сделать так, чтобы один раз собрал hidapi.lib и ее прилинковывать? чтобы длл не таскалась
Если в проекте либки есть конфигурация для статического билда - дальнейшие действия очевидны. Если нету - в настройках проекта меняем Configuration Type с Dynamic Library на Static Library и пробуем собрать. Если повезёт - соберётся, иначе - обогатите свой кладезь знаний, пополните словарь матерных неологизмов и заработаете массу новых навыков в процессе рукопашного исправления ошибок.kalobyte писал(а):а как это сделать? я давно компилил статически, но уже не помню и студия была 2003 что ли
размер видать не совпадает на другой платформе - типичненько для подобной ситуации. Но как показывают мои личные экзерцисы в процессе строгания вот этой штуки http://sourceforge.net/p/ats909hoggy/at ... ggyStudio/ прямой доступ к hid.dll работает вне зависимости от разрядности приложения и системы. Оба билда, как х86 так и х64 пашут с одним и тем-же устройством на Win 7 x64 идентично успешно. Так что проблема не в разрядности.kalobyte писал(а):я пробовал создать профиль х64, но там вылазит ошибка конвертации size_t, а я понятия не имею, что это такое
а ты можеш в курсе - через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает и там есть функция detach driverSiarzhuk писал(а):hid.dll работает вне зависимости от разрядности приложения и системы.
Достоверной информацией по этому случаю не обладаю. С другой стороны - доступ через hid.dll не требует администраторских прав для доступа - так что почему-бы и не присунуть устройству контрольный пакет со стороны? Нужно экспериментировать.kalobyte писал(а):через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает
Какого плана устройство? По мне так постоянно жить в ожидании подлянок со стороны системы или не дышать, боясь сделать подлянку системе - куда напряжённее чем потратиться на сборку платки с МК. Я для вышеупомянутого адаптера взял за пятнашку готовый модуль на PIC18F14K50 Devantech USB-GPIO12 для самодельщиков. Мне от него только IIC и нужен был. Платка идёт уже с бутлоадером - т.е. даже программатор не нужен.kalobyte писал(а):вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять