Conversion de std :: list en type convivial C

Quelle est la manière la plus élégante de renvoyer un object std::list depuis une fonction lib partagée (implémentée par le code C ++) à un consommateur C? Je sais que pour std::vector , nous pouvons renvoyer l’adresse du premier élément du vecteur et que le consommateur le traite comme un tableau, mais std :: list est implémenté comme un fichier lié.

Copiez le std::list dans un std::vector et retournez l’adresse du premier élément, comme vous l’avez déjà mentionné.

(Bien sûr, cela peut vouloir dire que vous ne voulez pas utiliser std::list en premier lieu.)

(Cette solution suppose que l’object auquel vous accédez est la propriété de la bibliothèque C ++. Si ce n’est pas le cas, vous devrez peut-être envisager d’allouer la mémoire de votre code C et de passer un pointeur dans la bibliothèque C ++ pour copier les données. )

vous pouvez toujours faire une copie:

 list lst; int *arr = new int[lst.size()]; copy(lst.begin(),lst.end(),arr); 

Si vous voulez que le code client manipule une liste, vous devrez définir un type C tel que:

 struct Node { int foo; float bar; // more data struct Node* next; }; 

et retourne un pointeur en tête de liste:

 struct Node* getData(); 

Ce qui signifie fondamentalement que vous devrez copier le contenu de votre std::list dans une structure de données de type C comme liste si vous souhaitez que le code client manipule une liste.

Sinon, vous pouvez copier le contenu de votre std::list dans un bloc de mémoire contigu, renvoyer ce bloc à l’appelant, mais dans ce cas, c’est à l’appelant de libérer la mémoire. Le renvoi d’un tableau signifie également que le nettoyage de la mémoire doit être effectué avec une fonction compatible avec la fonction utilisée pour allouer le bloc: votre implémentation utilisera probablement malloc et non new pour allouer ce bloc, de sorte que l’appelant puisse utiliser ultérieurement free le bloc.

Essayez quelque chose comme ça, pas besoin de std::copy si vous ne voulez pas l’utiliser:

 std::list aList; alist.push_back(1); alist.push_back(2); alist.push_back(3); std::vector aVector(alist.begin(), alist.end()); cFunction(&aVector[0], aVector.size()); 

La seule façon de le faire est de renvoyer un vide * à l’object. Ensuite, fournissez un ensemble de fonctions qui acceptent le void * et manipulent la liste dans le code C ++.

Modifier:

Pour ceux qui y vont Ehhh.

 std::list plop; void* getPlopList() { retutn &plop; } void appendToCPPList(void* list,int val) { static_cast*>(list)->push_back(val); } // Dont forget to declare the functions extern "C" 

Vous pouvez obtenir un iterator ou la liste et en remplir un vecteur:

 std::list nodes; // .. fill nodes std::vector nodeVector; std::copy(nodes.begin(); nodes.end(); std::back_inserter(nodeVector)); 

Et ensuite, vous pouvez travailler avec cela, tout comme avec le vecteur que vous connaissez bien.