代码之家  ›  专栏  ›  技术社区  ›  Falmarri

从C++调用C++方法

c c++
  •  7
  • Falmarri  · 技术社区  · 14 年前

    我已经有一段时间没用C了。我在一个项目中,我正在研究C++中的API。不管怎样,这些方法中的大多数都是C,所有返回值都是C结构。除了一个。我需要返回一个 vector<string> . 现在是我的问题。C++方法/库/从C中调用什么?我问,因为我不知道使用API的人是否会用C或C++编写,我觉得我应该只返回C结构。那就需要我归还一张支票 char** ,对吧?

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

    向量<字符串> -&燃气轮机; 字符**

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

    6 回复  |  直到 14 年前
        1
  •  6
  •   Michael Aaron Safyan    14 年前

    不,C不能使用C中不可用的C++特性。然而,C代码可以间接使用C++代码。例如,可以使用C++实现C函数,并且可以在接口中使用不透明类型,以便使用签名。 void* ,但是实现使用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;
    

    对于不透明类型,您将拥有以下内容:

     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*Value*。

        2
  •  6
  •   Matt Joiner    14 年前

    从技术上讲,您可以从C中调用任何东西,只要给定了C可见的函数名(在ABI级别忽略原型等)。当然,如果C不能以预期的方式生成参数,就不能期望得到正确的结果。通常显而易见的解决方案是将接口简化到C级。 char ** vector<string> . 不仅如此,如果你知道你打算用它做什么,很可能更快(而且更干净)。

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

    extern "C" char **lots_of_strings();
    

    vector<string> lots_of_strings(int);
    extern "C" char **lots_of_strings();
    

    bool 存在于C):

    bool lots_of_strings(vector<string> &);
    extern "C" int lots_of_strings(char ***);
    Whatever lots_of_strings(SomeArrayType &);
    

    记住,在每种情况下,C++都会选择具有最佳匹配签名的定义到调用站点,C将采取任何它可以(它总是一个具有匹配名称的单个函数)。

    您将发现通过组合对C隐藏C++ISM很有用 #ifdef 使用宏 __cplusplus .

        3
  •  5
  •   Matthew Flaschen    14 年前

    看到了吗 this FAQ . 基本上,你不能调用C++方法(成员函数),但是如果用ExtC C声明的话,你可以调用独立的函数。 char ** 这不是唯一的可能性,但可能是最直接的。您可以返回一个动态分配的 char * . 您必须使用out参数来向调用者提供长度(可以使用NULL终止它,但这可能不理想)。例如。

    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;
    }
    

        4
  •  0
  •   InsertNickHere    14 年前

    我前一段时间读过一些关于这方面的文章,iirc你可以使用c++代码/结构来编译。但是静态初始化有一点,如果我理解正确的话,你应该用c++写你的主函数来保证这个s.i.完成了,c.main没有。

        5
  •  0
  •   David Rodríguez - dribeas    14 年前

    如果您打算提供相同的功能,C和C++两个,我会尝试提供两个入口点,使您可以适应一个到另一个。注意,虽然您可以解决一个可以从C和C++中使用的接口,但在大多数情况下,C接口对于C++使用来说不是理想的。 char** 可能是C的一个好解决方案,但是用户将其转换回C++类型,并执行清理可以使用户代码混乱,反之亦然。

        6
  •  0
  •   Simon    14 年前

    如果您有可能修改您调用的代码,我建议将函数从返回向量改为:

    
    unsigned int MyFunction(char* buff, unsigned int numLines, unsigned int stride)