5

我想用 C 实现一个项目,但是用C++编写项目的某些部分然后从主C代码调用它们是很舒服的。
是否可以?!如果是的话,我该怎么做?!
提前致谢 :)

PS
我在我的C++代码中使用了一些库,例如OpenCV

4

4 回答 4

4

您需要使用常规 C 函数“包装”您的 C++ 接口,这些函数接受一个参数来指示它们将被调用的对象。例如,如果你有 C++

class A
{
    // .. boilerplate stuff...
    int SomeMethod(int n, float f);
};

然后与它一起,您可以声明一个函数,例如

extern "C" int A_SomeMethod(void* Obj, int n, float f)
{
    return(((A*)Obj)->SomeMethod(n, f));
}

如果您对 void* 的转换不满意,您可以实现某种从不透明句柄到A*. 但要点是您需要保留一些指向将调用该方法的对象的句柄/指针。为了获得指针/句柄,您需要将分配包装到:

extern "C" void* A_Instantiate()
{
    return new A;
}

C++ 文件应与具有上述功能的文件一起单独编译。C 编译的单独包含应包括上述所有函数的声明。

编辑:下面的警告和评论很重要;回答这个问题,“是的,可以从 C 调用 C++”,这是一种方法。这不是一个完整的方法,因为没有真正的机械方法来做到这一点,但这是一个开始。另外,不要忘记为delete等创建另一个调用。

于 2013-03-16T18:25:44.617 回答
0

是的,您需要将其指定为

外部“C”

这样,它将使函数具有“C”链接,然后C代码可以像在C中一样调用您的函数。这个函数名称不会被破坏,因为C不支持重载。

这里让我引用@Faisal Vali:

  • extern "C" 是一个链接规范
  • 每个编译器都需要提供“C”链接
  • 链接规范应仅出现在命名空间范围内
  • 所有函数类型、函数名和变量名都有语言链接
  • 具有不同语言链接的两个函数类型即使在其他方面相同也是不同的类型
  • 联动规格嵌套,内一决定最终联动
  • 类成员忽略 extern "C"
  • 至多一个具有特定名称的函数可以具有“C”链接(无论命名空间如何)
  • extern "C" 强制函数具有外部链接(不能使其静态)
  • 从 C++ 到用其他语言定义的对象以及从其他语言到用 C++ 定义的对象的链接是实现定义和语言相关的。只有在两种语言实现的对象布局策略足够相似的情况下,才能实现这样的联动

在这里查看费萨尔瓦利的答案

于 2013-03-16T18:24:34.270 回答
0

问:我能否从 C++ 访问我的 C 代码,反之亦然?

答:是的。

1)主要是extern "C" { ...}在所有标题中使用来表示仅 C 的函数和数据,如下所示:

http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

/* Header file foo.h */
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif

/* These functions get C linkage */
void foo();

struct bar { /* ... */ };

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
}
#endif

2) 通常的场景是一个 C++ 主程序,它调用 C 和 C++ 函数和结构的混合。结构和函数都在头文件中声明,并且都有“#ifdef __cplusplus/extern C”。

3) 这是一个关于混合 C 和 C++ 的常见问题解答:

http://www.parashift.com/c++-faq/mixing-c-and-cpp.html

于 2013-03-16T18:24:40.403 回答
0

除非严格要求,否则这仅适用于彻头彻尾的受虐狂。这样做需要双方都非常小心,并且今天可以很好地工作,并在下一次编译器更新时爆炸式地爆炸。C++ 需要大量运行时帮助,通常不支持从 C 中可靠地工作。您可以从 C++ 调用 C,这是官方支持的(以及标准的一部分extern "C"等)。

最好的办法可能是在 C 和 C++ 处理的子集中编写 C(细微差别的起点是this)并使用 C++ 编译器进行编译。或者克服它并决定你最喜欢哪种语言。

于 2013-03-16T19:12:48.823 回答