将std :: list转换为C友好类型

时间:2010-01-18 16:38:22

标签: c++ c stl

std::list对象从共享库函数(由C ++代码实现)返回给C使用者的最优雅方法是什么?我知道对于std::vector,我们可以返回向量的第一个元素的地址,并让消费者将其视为一个数组,但是std :: list被实现为链接的lis。

6 个答案:

答案 0 :(得分:9)

std::list复制到std::vector并返回第一个元素的地址,如上所述。

(当然,这可能意味着您不希望首先使用std::list。)

(此解决方案假定C ++库正在访问的对象拥有 - 如果不是这种情况,您可能需要考虑从C代码中分配内存并传递指向C ++库的指针,用于复制数据。)

答案 1 :(得分:5)

你总是可以复制一份:

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

答案 2 :(得分:2)

如果您希望客户端代码操作列表,则必须定义C类型:

struct Node
{
  int foo;
  float bar;
  // more data

  struct Node* next;
};

并返回指向列表头部的指针:

struct Node* getData();

这基本上意味着如果您希望客户端代码操作列表,则必须将std::list的内容复制到类似C的列表数据结构。

否则,您可以将std::list的内容复制到连续的内存块中,将此块返回给调用者,但在这种情况下,调用者有责任释放内存。返回数组还意味着必须使用与用于分配块的函数兼容的函数来完成内存清理:您的实现可能会使用malloc而不是new来分配此块,因此调用者以后可以在块上使用free

答案 3 :(得分:2)

尝试这样的事情,如果你不想使用它,则不需要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());

答案 4 :(得分:2)

唯一的方法是向obejct返回void *。 然后提供一组函数来接受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"

答案 5 :(得分:0)

你可以得到一个迭代器或列表并用它填充一个向量:

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

然后你可以像使用你熟悉的矢量一样使用它。