【问题标题】:How can I call a C++ function from C? [duplicate]如何从 C 调用 C++ 函数? [复制]
【发布时间】:2010-10-25 04:17:42
【问题描述】:

我有一个头文件声明了将指向 C++ 对象的指针作为参数的函数。实现在一个单独的 C++ 文件中。即使参数需要是 C++ 对象指针,如何在 C 中包含此标头并在 C 中使用函数?

【问题讨论】:

标签: c++ c


【解决方案1】:

不幸的是,我的第一次尝试回答了错误的问题....

对于你提出的问题...

正如有人指出的那样,您可以绕过void *'s。这也是我要推荐的。就 C 而言,指向 C++ 对象的指针应该是完全不透明的。

如果 C++ 函数位于全局命名空间中,它们也可以标记为 extern "C"。这是一个例子:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#endif

extern int myfunction(int, void *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, void *vobptr)
{
    ClassType *ob = static_cast<ClassType *>(vobptr);
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, void *opaque_classtype_ptr) {
    myfunction(x, opaque_classtype_ptr);
    /* do stuff with buf */
}

另一种选择是在 C 中创造性地使用 typedefs 来做基本相同的事情。恕我直言,这很丑陋,但无论如何这里有一个例子:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType;  /* This is incredibly ugly. */
#endif

extern int myfunction(int, ClassType *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, ClassType *ob)
{
    // Do stuff with ob
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, ClassType *opaque_classtype_ptr) {
    myfunction(x, opaque_classtype_ptr);
    /* do stuff with buf */
}

【讨论】:

  • 有条件地使用extern "C" 的更常见的习语可以在我的回答stackoverflow.com/questions/2941126/… 中找到(它不适合评论)。它不涉及重复您的原型,因此更不容易出现拼写错误。
  • @Ken Bloom - 这是有道理的,我将编辑我的版本以符合要求,尽管它使第二个示例中的愚蠢技巧不太清楚。
  • 如果它使指针技巧不那么清晰,那么不要使用它。
  • 如果它非常丑陋,那么正确的方法是什么?!
  • @Alexis - 在 C++ 函数中涉及 static_cast 的另一种方式。另一种方式的丑陋之处在于函数采用不同的类型,具体取决于哪种语言看到声明。对于普通的指针类型,这可能不是问题。但是对于一个函数指针类型,这可能会导致各种奇怪的事情。一般来说,像“丑陋的方式”那样快速而松散地使用类型系统只是一个坏主意。
【解决方案2】:

如果您的 C 代码只需要传递指针,并最终将其传递回某些 C++ 以实际处理它指向的对象,您应该能够在 C 代码中使用 void *,并在返回 C++ 时转换回 T *

如果您计划实际使用指针的 C 代码,那么您几乎会陷入对编译器所做的逆向工程,并尝试足够接近地模拟它以使事情正常运行。即使充其量,这也将是丑陋和脆弱的。

【讨论】:

    【解决方案3】:

    制作一个 C++ 封装模块,但其外部函数声明为 extern "C"。这将允许您从 C 中干净地访问 C++ 代码。当然,包装器应该用 void 指针(快速而肮脏的解决方案)或指向不完整 struct 类型的指针替换任何指向 C 中不可表示的类型(即类)的指针(只要它们被一致使用,就会提供一定程度的类型安全。

    【讨论】:

      【解决方案4】:

      在阅读了有关该主题的各种帖子后,将其保留为最容易理解的方法。

      http://research.engineering.wustl.edu/~beardj/Mixed_C_C++.html

      此外,在 netbeans 中,该示例开箱即用,无需接触 makefile。

      【讨论】:

        【解决方案5】:

        秘密是“extern C”,其主要目的是防止名称修饰。

        【讨论】:

          【解决方案6】:

          你不能。您必须创建一个与 C 兼容的抽象层:

          typedef struct foowrapper *foohandle;
          
          foohandle foo_create();
          void foo_delete(foohandle);
          
          int foo_getvalue(foohandle);
          void foo_dosomething(foohandle, const char* str);
          

          【讨论】:

            【解决方案7】:

            查看此链接:-

            http://developers.sun.com/solaris/articles/mixing.html

            该链接包含以下主题:

            • 使用兼容的编译器

            • 从 C++ 源代码中访问 C 代码

               -  Accessing C++ Code From Within C Source
              
            • 混合 IOstream 和 C 标准 I/O

            • 使用指向函数的指针

            • 处理 C++ 异常

            • 链接程序

            【讨论】:

            • 1.不鼓励在 SO 上发布没有解释、描述或摘要的链接(如果您链接到的页面出现故障,您的答案将变得毫无用处,这会使读者更难获得各种答案的概述,而且有些人想知道他们点击的不仅仅是垃圾邮件,甚至与问题相关)。 2. 您甚至没有将其格式化为链接。
            猜你喜欢
            • 2021-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-26
            • 2023-04-08
            相关资源
            最近更新 更多