Указатель на массив с приведением типов

vde69
Offline
Зарегистрирован: 10.01.2016

что-то туплю и не соображу правильно-ли делаю сохранение и чтение двухбайтового числа из памяти которая выделана как массив, соответственно 

uint8_t *data_device - это указатель на адрес первого байта массива, соответственно число должно лежать в 10...11 байтах этого массива  

int16_t GetT(const uint8_t *data_device) { 
     return (int16_t)data_device[9]; 
}
void SetT(uint8_t *data_device, const int16_t Term) { 
    (int16_t)data_device[9] = Term; 
}

зы

способы с чтением младшего и старшего байта не предлогайте, вместо типа int16_t может быть что-то более сложное, способ с "memcpy"  то же мне в данном конкретном случае не очень нравится.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Сначала закастовали указатель на элемент исходного массива требуемым типом - получили указатель на кастомный тип. Потом разыменовали указатель на кастомный тип - получили значение.

vde69
Offline
Зарегистрирован: 10.01.2016

у меня в одном массиве значения разного размера, по этому кастовать указатель не могу

sadman41
Offline
Зарегистрирован: 19.10.2016

Как это - в массиве и разного размера? Я вижу uint8 сплошной.
Я так понимаю, что структуру собрались байтстримом передавать?

vde69
Offline
Зарегистрирован: 10.01.2016

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

а изначально массив описан как некий байтовый буфер (не кольцевой) в котором могут быть разнотипные данные

vde69
Offline
Зарегистрирован: 10.01.2016

может сначала сделать (void*) а потом его кастануть?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

vde69 пишет:

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

а изначально массив описан как некий байтовый буфер (не кольцевой) в котором могут быть разнотипные данные

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

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

vde69 пишет:

может сначала сделать (void*) а потом его кастануть?

А чем это должно помочь ?

"Вот так кури :"

Вариант 1: *((uint16_t*)(&(data_device[9])))

Вариант 2 : *((uint16_t*)(data_device+9))

Только вот объясните мне, если вы путаетесь в этих преобразованиях, то нахрена вы их юзаете, если есть понятные вам ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Не знаю, чем указатель на покрывающую структуру (они же хлеба не просят) не угодил, но если уж хотите просто взять иной тип из байтстрима, то как-то так:

int16_t GetT(const uint8_t *data_device) {
  return *((int16_t*)&data_device[9]);
}
void SetT(uint8_t *data_device, const int16_t Term) {
  *((int16_t*)&data_device[9]) = Term;
}

 

Еще можно по-модному через static_cast, но я что-то синтаксиса не помню.

vde69
Offline
Зарегистрирован: 10.01.2016

наверно так то-же будет верно

  int16_t GetT(const uint8_t *data_device) { return *((int16_t*)(data_device+9)); }
  void SetT(uint8_t *data_device, const int16_t Term) { *((int16_t*)(data_device+9)) = Term; }

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

brokly пишет:

Вариант 2 : *((uint16_t*)(data_device+9))

vde69
Offline
Зарегистрирован: 10.01.2016

для меня C++ немного не удобный в синтаксисе, я изначально паскалист :) там немного пожоще с преобразованиями.

а юзаю это по тому как если в кратце - это разбор некоторой не системной информации из буфера, то есть в буфере может лежать данные от разных типов датчиков, и каждый из этих датчиком может менять свою структуру.

в паскале есть record типа структуры но инвариантный (принимающий разные варианты в зависимости от типов данных), вроде в с++ простых аналогов я не видел, хотя возможно просто не увидел.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

В си это называется юнит (unit). Почитайте, создаете альтернативные структуры, а потом объединяете их в юнит. Правда могут возникнуть проблемы с выравниванием данных, они , как правило, обходятся нормально. 

Я к чему спрашивал, компилятор совсем не дурак, он может так оптимизировать, что вот эти самые сложения байт с умножением для приведения из 8 бит в 16 могут выполняться и без умножения. Просто такие откровенные касты платформо зависимы, ни к чему хорошему это не приводит. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

vde69 пишет:
в паскале есть record типа структуры но инвариантный (принимающий разные варианты в зависимости от типов данных), вроде в с++ простых аналогов я не видел, хотя возможно просто не увидел.

Т.е. Вы не знаете, чего хотите? А чего делать с тем, что не знаете - знаете? А как опознаете, то, что не знаете?

Херня какая-то.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а так не прокатит? пропробуй

int16_t *ptr = reinterpret_cast<int16_t *>(&data[9]);
return *ptr;

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

mykaida пишет:

vde69 пишет:
в паскале есть record типа структуры но инвариантный (принимающий разные варианты в зависимости от типов данных), вроде в с++ простых аналогов я не видел, хотя возможно просто не увидел.

Т.е. Вы не знаете, чего хотите? А чего делать с тем, что не знаете - знаете? А как опознаете, то, что не знаете?

Херня какая-то.

Это как раз заскоки паскаля :) Скорее всего он хочет получив массив по сигнальному признаку его разобрать  прям в буфере, типа память экономит.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

DetSimen пишет:

а так не прокатит? пропробуй

int16_t *ptr = reinterpret_cast<int16_t *>(&data[9]);
return *ptr;

Ты конечно жОстко рубанул :) Вот так ошибется, а где никада не узнает :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

brokly пишет:

Ты конечно жОстко рубанул 

O_O   

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

b707
Offline
Зарегистрирован: 26.05.2017

brokly пишет:

Это как раз заскоки паскаля :) Скорее всего он хочет получив массив по сигнальному признаку его разобрать  прям в буфере, типа память экономит.


и в чем проблема? Это, вроде, несложно. Можно вручную... А можно заранее определить несколько структур и приводить массив к нужному типу по сигнальному признаку

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

b707 пишет:
brokly пишет:

Это как раз заскоки паскаля :) Скорее всего он хочет получив массив по сигнальному признаку его разобрать  прям в буфере, типа память экономит.

и в чем проблема? Это, вроде, несложно. Можно вручную... А можно заранее определить несколько структур и приводить массив к нужному типу по сигнальному признаку

Я вроде не говорил, что проблема....

vde69
Offline
Зарегистрирован: 10.01.2016

brokly пишет:

Это как раз заскоки паскаля :) Скорее всего он хочет получив массив по сигнальному признаку его разобрать  прям в буфере, типа память экономит.

я хочу получить универсальную шину данных с которой будет работать любой объект созданый на основе базового класса, что-то вроде EnterpriseData в 1с,  там она собрана на XML, здесь такой формат невозможно организовать из-за малой памяти. По существу пытаюсь сделать аналог фабрики XDTO на обьектной модели c++.

Совсем универсально у меня не выйдет, но для меня вполне пойдет

vde69
Offline
Зарегистрирован: 10.01.2016

для начала я реализовал аналог TListCustom (по существу массив ссылок) , каждый новый объект регистрирует в нем ссылку на объект и на выделеную из кучи память под данные, для каждого объекта памяти может быть разное количество, например для датчиков температуры регистрируется один объект по номеру шины OneWire и место для хранения нескольких измерений температуры, плюс статус для каждого датчика. Этим я конечно не сильно экономлю память а просто делаю доступным данные объекта любым другим объектам.

То есть я реализовываю динамическое определение и подключение датчиков (и других устройств) к общей шине без создания новых объектов а только добавлением памяти и включением их в TList.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

vde69, это для систем где есть CD карточка, куда вы будете пихать ваши файлы 1с.  Создать виртуальный диск из кучи в ОЗУ у вас не выйдет.