我有一个库函数,它创建并返回(通过值)指向堆上某些对象的指针向量。当我使用c ++时,这很好用,但现在我需要导出这个函数,以便它可以与C链接,我对如何以干净的方式实现这一点感到困惑。
我的第一个天真的尝试如下:
airport_t **listAiportsByCode(const char *code) {
vector<airport_handle*> airports;
// Fill up vector with pointer to airports on the heap ...
airports.push_back(nullptr);
airport_t** c_airports = airports.data();
return c_airports;
}
由于机场矢量是堆栈分配,显然不会起作用。
我是否需要在堆上分配一个数组并简单地记录在使用后需要删除该数组?
airport_t **listAiportsByIATA(const char *iata) {
vector<airport_handle*> airports;
// Fill up vector with airports ...
airports.push_back(nullptr);
airport_t* c_airports = new airport_t*[BUFFER];
std::copy(airports.begin(), airports.end(), c_airports);
return c_airports;
}
我习惯于使用高级语言进行编程,这对于这样一个简单的函数来说似乎是一个太难看的设计。
答案 0 :(得分:2)
这很难看,但那是C的做事方式。 您可以采取您的方法,或获取airport_t **作为参数,让客户端为您分配内存。 您只需要填充客户端分配的内存,并返回插入的元素数。
int listAiportsByIATA(const char *iata, airport_t **c_airports) {
vector<airport_handle*> airports;
// Fill up vector with airports ...
airports.push_back(nullptr);
std::copy(airports.begin(), airports.end(), c_airports);
return airports.size();
}
然而,这个解决方案会有另一个问题,客户端需要为你分配足够的内存来填充。所以你可能想要添加另一张支票。
答案 1 :(得分:2)
对于处理内存我认为你唯一的选择是分配数组并让客户端整理它或让客户端分配数组。
不使用向量并直接写入数组也可能更清晰吗?
为客户分配数组:
airport_t **listAiportsByIATA(const char *iata) {
airport_t** c_airports = new airport_t*[BUFFER];
// Fill up vector with airports ...
for (airport_t** airport = c_airports; airport < c_airports + BUFFER; ++airport) {
*airport = nullptr;
}
return c_airports;
}
客户端分配数组:
void listAiportsByIATA(const char *iata, airport_t ** c_airports, int maxSize) {
// Fill up vector with airports ...
for (airport_t** airport = c_airports; airport < c_airports + maxSize; ++airport) {
*airport = nullptr;
}
}