首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从C++调用C++方法

从C++调用C++方法
EN

Stack Overflow用户
提问于 2010-08-04 14:24:09
回答 6查看 1.5K关注 0票数 7

我已经有一段时间没有直接使用C语言了,我正在做一个项目,我正在用C++编写一个应用程序接口。这些方法中的大多数都是C语言,并且所有的返回值都是C结构。只有一个例外。我需要返回一个vector<string>的方法。现在我的问题来了。C++方法/库/任何东西都可以从C调用吗?我问这个问题是因为我不知道使用API的人是用C还是C++写的,我觉得我应该只返回C结构。这需要我返回一个char**,对吗?

我希望这是有意义的,如果没有的话:

dr版本-如果C返回C结构,我可以从C调用C++方法吗?如果是这样,是最好的(唯一?)vector<string> -> char**的等效返回值

更新: C++方法是简单的全局方法。它们中没有类或面向对象的东西。除了我的向量问题之外,唯一特定于C++的是几个stringstreams

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-08-04 14:32:35

不,C不能使用C中没有的C++特性。但是,C代码可以间接使用C++代码。例如,您可以使用C++实现一个C函数,并且可以在接口中使用不透明类型,以便签名使用void*,但该实现使用C++类。

在C中,向量的等价物可能更接近:

代码语言:javascript
运行
复制
 typedef const char* c_string_type;
 typedef struct c_string_array {
     c_string_type* c_strings;
     int c_strings_count;
  } c_string_array_t;

对于不透明类型,您可能会有类似以下内容的内容:

代码语言:javascript
运行
复制
 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*。

票数 6
EN

Stack Overflow用户

发布于 2010-08-04 14:40:46

从技术上讲,你可以从C中调用任何东西,只要给定了一个C-可见的函数名(原型等在ABI级别被忽略)。当然,如果C不能以预期的方式生成参数,就不能期望正确的结果。通常,最明显的解决方案是将接口简化到C级别。对于具有vector<string>的最大公分母,char **是一个很好的选择。不仅如此,如果你知道你打算用它做什么,很可能会更快(更干净的IMHO)。

关于C可见性:函数名不能与任何其他C可见函数共享。如果您希望您的C++函数可以从C调用,这可能是一个很好的原型示例:

代码语言:javascript
运行
复制
extern "C" char **lots_of_strings();

如果参数签名不同,C++将允许您重载仅在C++中可见的函数,并允许它们与C版本共存:

代码语言:javascript
运行
复制
vector<string> lots_of_strings(int);
extern "C" char **lots_of_strings();

如果您想提供几种方法来调用它,适合于调用语言,您可以尝试这样做(忽略延迟初始化的缺点,以及bool存在于C中的事实):

代码语言:javascript
运行
复制
bool lots_of_strings(vector<string> &);
extern "C" int lots_of_strings(char ***);
Whatever lots_of_strings(SomeArrayType &);

请记住,在每种情况下,C++都会选择与调用点具有最佳匹配签名的定义,而C将尽可能地使用它(这始终是具有匹配名称的单个函数)。

您会发现,通过将C++isms与宏__cplusplus组合在一起,在C中隐藏#ifdef是很有用的。

票数 6
EN

Stack Overflow用户

发布于 2010-08-04 14:31:16

参见this FAQ。基本上,您不能调用C++方法(成员函数),但是如果独立函数是用外部C声明的,则可以调用它们。char **不是唯一的可能性,但它可能是最直接的。您可以返回一个动态分配的char *数组。您必须使用out参数为调用者提供长度(您可以空终止它,但这可能并不理想)。例如。

代码语言:javascript
运行
复制
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;
}

您必须以某种方式释放内存。要么提供一个函数,要么记录调用者应该如何做。如果单个字符串是动态分配的,请不要忘记释放它们。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3403088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档