Что самый изящный путь состоит в том, чтобы возвратить a std::list
объект от общей функции lib (реализованный кодом C++) потребителю C? Я знаю для std::vector
, мы можем возвратить адрес 1-го элемента вектора и сделать, чтобы потребитель рассматривал его как массив, но станд.:: список реализован как связанные литии.
Копировать STD :: Список
на std :: vector
и вернуть адрес первого элемента, как вы уже упоминалось.
(Конечно, это может означать, что вы не хотите использовать STD :: Список
в первую очередь.)
(это решение предполагает, что доступ к объекту Владелец Библиотекой C ++ - если это не так, вам может потребоваться рассмотреть возможность рассмотрения памяти из вашего C-кода и передавать указатель в библиотеку C ++ для копирования данных.)
всегда можно сделать копию:
list<int> lst;
int *arr = new int[lst.size()];
copy(lst.begin(),lst.end(),arr);
Если вы хотите, чтобы клиентский код манипулировал списком, вам нужно будет определить тип C типа:
struct Node
{
int foo;
float bar;
// more data
struct Node* next;
};
и вернуть указатель на заголовок списка:
struct Node* getData();
Что, по сути, означает, что вам нужно будет скопировать содержимое вашего std::list
в структуру данных списка C типа, если вы хотите, чтобы клиентский код манипулировал списком.
Иначе вы можете скопировать содержимое вашего std::list
в смежный блок памяти, вернуть этот блок вызывающему абоненту, но в этом случае ответственность за освобождение памяти лежит на вызывающем абоненте. Возвращение массива также означает, что очистка памяти должна быть произведена с помощью функции, совместимой с функцией, которую вы использовали для выделения блока: ваша реализация, скорее всего, будет использовать malloc
, а не new
для выделения этого блока, чтобы в дальнейшем вызывающий абонент мог использовать free
на блоке.
sqlcmd -E -S SERVER\INSTANCE -Q "sp_databases"
-121--1506612- EXEC sp_databases
или
SELECT NAME FROM sys.sysdatabases
или
EXEC sp_msForEachDB 'PRINT ''?''';
-121--1506613- Единственный способ - вернуть пустоту * в объект. Затем предоставьте набор функций, которые принимают void * и манипулируют списком в коде C++.
Для тех, которые идут Ehhh.
std::list<int> plop;
void* getPlopList()
{
retutn &plop;
}
void appendToCPPList(void* list,int val)
{
static_cast<std::list<int>*>(list)->push_back(val);
}
// Dont forget to declare the functions extern "C"
Попробуйте что-нибудь подобное, не нужно std::copy
, если не хотите его использовать:
std::list<int> aList;
alist.push_back(1);
alist.push_back(2);
alist.push_back(3);
std::vector<int> aVector(alist.begin(), alist.end());
cFunction(&aVector[0], aVector.size());
Вы можете получить итератор или список и заполнить вектор с ним:
std::list<Node> nodes;
// .. fill nodes
std::vector<node> nodeVector;
std::copy(nodes.begin(); nodes.end(); std::back_inserter(nodeVector));
, а затем вы можете работать с ним, как и с вектором, с которым вы знакомы.