Как установить значение со смещением памяти из указателя const void?

#c #pointers

#c #указатели

Вопрос:

У меня есть указатель, возвращенный из функции

 rs2::video_frame frame = frames.get_color_frame();
const void* data = frame.get_data();
 

Я знаю, что этот указатель представляет собой массив значений RGB (т.Е. 3 char с) размера frame.get_data_size() .

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

 int bpp = frame.get_bytes_per_pixel();
int width = frame.get_width();
int height = frame.get_height();

int offset = (y * width * bpp)   (x * bpp);
int r = offset;
int g = offset   1;
int b = offset   2;

// ?data[r] = newRed;
// ?data[g] = newGreen;
// ?data[b] = newBlue;
 

Комментарии:

1. Приведите его к указателю типа pixel, затем используйте смещения. void* это не то, чем вы можете управлять напрямую.

2. Вам нужно указать регистр data char* , чтобы разыменовать его.

3. @tadman Я знаю о приведении и все такое. Я программировал на C / C немного, много лет назад, но вопрос в том, как .

4. Если вы вернулись к программированию на C , то пришло время освежить основы. C и C имеют здесь совершенно разные подходы, поэтому не путайте их с C / C , что не имеет значения. Используйте static_cast для C .

5. @tadman чтобы дать вам представление, в последний раз, когда я касался компилятора, был на 386, используя TurboC 3.5. Некоторое время назад.

Ответ №1:

Вам было бы проще, если бы у вас был объектно-ориентированный подход:

 struct Pixel {
    short red;
    short green;
    short blue;
};
 

Пусть ваш фрейм работает с std::vector<Pixel> pixels ; который возвращается по ссылке. std::vector<Pixel>amp; get_data();

 pixels[y * width   x].red = newRed;
pixels[y * width   x].green = newGreen;
pixels[y * width   x].blue = newBlue;
 

Если вам действительно нужно работать void* , попробуйте это

 char* data = static_cast<char*>(const_cast<void*>(dataframe.get_data()));
// Since you also const cast it becomes more and more dangerous. You really need know what you are doing.

size_t bpp = frame.get_bytes_per_pixel();
size_t width = frame.get_width();
size_t height = frame.get_height();

size_t offset = (y * width * bpp)   (x * bpp);
size_t r = offset;
size_t g = offset   1;
size_t b = offset   2;

*(data   r) = newRed;
*(data   g) = newGreen;
*(data   b) = newBlue;

 

Для массовых обновлений вы можете использовать memset .

См. https://godbolt.org/z/xvc1xs за подробностями.

Комментарии:

1. вам также нужно отбросить константу, чтобы написать

2. FWIW memset сработал! memset((void *)data r, (char) newRed, (size_t) 1);

3. Вы правы, указатель должен быть не const таким, как у меня в моем примере godbolt. Я исправляю это в ответе. Ваши memset работы, потому const что вы отбрасываете