stl — Оболочка C ++ для массива указателей, возвращаемых функцией C

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

int handler(int argc, sometype **argv);

Теперь я бы хотел, чтобы вызывающий код C ++ предоставлял больше функций-обработчиков C ++, например:

int handler(std::vector<sometype*> args);

Изменение типа обработчика не сложно, я просто должен предоставить свой собственный handler который затем вызывает предоставленный пользователем обработчик. Так что мне нужно создать std::vector и скопировать содержимое argv внутрь.

Однако я не хочу копировать весь список указателей, если это возможно. К сожалению, я думаю, что это невозможно сказать std::vector использовать уже выделенный блок памяти для своего внутреннего массива, причем массив является статическим, и его следует учитывать const,

Есть ли какой-нибудь тип STL, похожий на std::vector что можно использовать для упаковки предварительно выделенных массивов в стиле C с более дружественным интерфейсом? Он должен поддерживать размер запроса и итерации, аналогично std::vector,

Благодарю.

3

Решение

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

template<typename I>
int handler(I begin, I end);

handler(argv, &argv[argc]);

Это все еще не идеальное решение, но оно будет более общим и позволит вам использовать уже существующий массив.

1

Другие решения

Я не уверен, что вы спрашиваете, но если бы мне дали прототип этой функции

int handler(int argc, const sometype *const *argv);

Вот сделайте обертку C ++:

int handler(const std::vector<sometype*>& arg)
{return handler(arg.size(), &arg[0]);} //no copies

template<class const_iterator>
int handler(const_iterator begin, const_iterator end) //can pass any structure
{return handler(std::distance(begin, end), &*begin);} //no copies

Вот как я мог бы реализовать этот API в C ++:

int handler(int argc, const sometype *const*argv) {
const std::vector<const sometype*> arg(argv, argv+argc); //this will copy the pointers
//stuff
}

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

Доказательство составления: http://ideone.com/BkSVd

1

Ну, я уверен, что если вы знаете о :: vector, вы смотрели в :: массив?

http://www.cplusplus.com/reference/stl/array/

Однако основная проблема — наложение объектов на существующую память — напоминает мне о простых анализаторах пакетов: создайте структуру объекта, а затем наложите ее, переместив ее ссылку на известные данные. Я не уверен, что вы можете сделать это в своей проблеме, но это был бы первый путь, который я бы рассмотрел.

Примечание: я не знаю точно, как устроен массив std :: так очевидно, что это будет трудно реализовать: /

0

На какой тип данных будут ссылаться эти элементы указателя?

Кто является владельцем этих элементов указателя, я имею в виду, являются ли эти элементы просто ссылками в структуре коллекции / данных, или эта коллекция отвечает за распределение, освобождение этих элементов?

Эти предметы одинакового типа или одинакового размера?

Например, массив символов разного размера или объекты, которые могут отличаться базовым классом, но происходят от общего предка.

Все эти темы могут быть рассмотрены, чтобы решить, какую библиотеку, объектно-ориентированную или нет, и какую структуру данных или коллекцию использовать.

Кажется, std и Boost должны быть первым вариантом поиска в первую очередь. Но иногда вам может понадобиться создать свою собственную коллекцию.

Кажется, ваша библиотека требует больше похожей на индексируемую концепцию List, чем Array, хотя иногда она взаимозаменяема.

Приветствия.

0
По вопросам рекламы [email protected]