因为我已经使用过C,所以已经有一段时间了。我正处于一个我正在使用C ++编写API的项目。无论如何,这些方法中的大多数都只是C,并且所有返回值都是C结构。除了一个。我需要一种方法来返回vector<string>
。现在这是我的问题。 C ++方法/库/可以从C调用吗?我问,因为我不知道使用API的人是否会用C或C ++编写,我觉得我应该只返回C结构。这需要我返回char**
,对吗?
我希望有意义,如果没有:
tl; dr version - 如果它返回C结构,我可以从C调用C ++方法,如果是,那么vector<string>
的最佳(仅?)等效返回值 - &gt; char**
?
更新:C ++方法只是全局方法。它们中没有类或面向对象的东西。除了我的向量问题之外,C ++特有的唯一的东西是stringstreams
答案 0 :(得分:6)
不,C不能使用C中不可用的C ++特性。但是,C代码可以间接使用C ++代码。例如,您可以使用C ++实现C函数,并且可以在接口中使用opaque类型,以便签名使用void*
,但实现使用C ++类。
vector&lt; string&gt;的等价物在C中可能更接近:
typedef const char* c_string_type;
typedef struct c_string_array {
c_string_type* c_strings;
int c_strings_count;
} c_string_array_t;
对于opaque类型,你会有以下几点:
typedef void* c_string_array_t;
int c_string_array_length(c_string_array_t array);
const char* c_string_array_get(c_string_array_t array, int index);
然后你可以秘密地(在C ++实现中)将std :: vector *强制转换为void *。
答案 1 :(得分:6)
只要给出C-visible函数名称(在ABI级别忽略原型等),您就可以从技术上调用C中的任何内容。当然,如果C无法以预期的方式生成参数,则无法获得正确的结果。通常,显而易见的解决方案是将接口简化为C级。对于char **
的最大公分母,vector<string>
是一个很好的选择。不仅如此,如果你知道你打算用它做什么,可能更快(更清洁恕我直言)。
关于C可见性:函数名称不能与任何其他C可见函数共享。如果您希望C ++函数可以从C调用,这可能是原型的一个很好的例子:
extern "C" char **lots_of_strings();
如果参数签名不同,C ++将允许您使用仅从C ++可见的函数重载,并允许它们与C版本共存:
vector<string> lots_of_strings(int);
extern "C" char **lots_of_strings();
如果你想提供几种方法来调用它,适用于调用语言,你可以试试这个(忽略后期初始化的弊端,以及C中存在bool
的事实):
bool lots_of_strings(vector<string> &);
extern "C" int lots_of_strings(char ***);
Whatever lots_of_strings(SomeArrayType &);
请记住,在每种情况下,C ++都会选择与调用站点具有最佳匹配签名的定义,而C将采用它可以做的任何事情(它总是具有匹配名称的单个函数)。
通过将#ifdef
与宏__cplusplus
相结合,您会发现从C隐藏C ++主义非常有用。
答案 2 :(得分:5)
见this FAQ。基本上,你不能调用C ++方法(成员函数),但如果用extern C声明它们就可以调用独立函数。char **
不是唯一的可能性,但它可能是最直接的。您可以返回动态分配的char *
数组。您将不得不使用out参数来为调用者提供长度(您可以使用NULL终止它,但这可能并不理想)。 E.g。
char **get_string_list(size_t *len)
{
char **array;
size_t actual_len;
// ...
*len = actual_len;
array = (char **) malloc(sizeof(char *) * actual_len);
// ...
return array;
}
你必须以某种方式释放记忆。提供函数或记录调用者应该如何执行它。如果动态分配,请不要忘记释放单个字符串。
答案 3 :(得分:0)
我前段时间读了一些关于这个的内容,并且你可以使用c ++编译的C ++代码/结构。但是有一些关于静态初始化的东西,如果我理解正确,你应该用c ++编写你的main函数保证这个si完成了,C主要做不到。
答案 4 :(得分:0)
如果您打算为C和C ++提供相同的功能,我会尝试提供两个入口点,以便您可以相互适应。请注意,虽然您可以选择可以在C和C ++中使用的接口,但在大多数情况下,C接口将不适合C ++使用(使用char**
可能是C的良好解决方案,但拥有用户将其转换回C ++类型并执行清理会使用户代码混乱),反之亦然。
答案 5 :(得分:0)
如果您有可能修改您正在调用的代码,我建议您更改函数,将向量返回到以下内容:
unsigned int MyFunction(char* buff, unsigned int numLines, unsigned int stride)
其中numLines是分配的字符串数量,stride是字符串的大小。这样你的函数就不需要分配任何你需要担心的内存了。这一切都由来电者处理。函数的返回值是使用的字符串数量。