C中调用C++函数

在C中调用C++函数(非成员函数)

如果我们的C++函数有个C连接符(extern “C”),它可以被C编译器编译过的C函数直接调用。被C连接符声明过的C++函数可以拥有C++的一切特征,但是如果我们想在C中调用这个函数,他的参数和返回值必须能被C所支持。例如,一个函数的形参是和IOstream有关的类,那么很遗憾,这就没什么(简单的)办法去让C编译器明白这是什么玩意,也就不能被编译通过了。C不支持C++中的类、模板和references这些特征。

这是一个有C连接符声明的C++函数:

#include <iostream>

extern "C" int print(int i, double d)

{

    std::cout << "i = " << i << ", d = " << d;

}

我们可以在 C C++ 共享的头文件中声明如下的一个 print 函数
#ifdef __cplusplus

extern "C"

#endif

int print(int i, double d);

对于重载的函数,我们最多只能用 extern “C” 声明其中的一个,因为同一个名字只能当作一个 C 函数,我们可以像下面的例子这样在 C++ 中做一下包装来解决这个问题:
int    g(int);

double g(double);

extern "C" int    g_int(int i)       { return g(i); }

extern "C" double g_double(double d) { return g(d); }

然后 C 中的包装函数是这样的:
int g_int(int);

double g_double(double);

我们也必须在用模板的时候对模板函数做一下包装,因为模板函数不能被 extern “C” 声明,例子如下:
template<class T> T foo(T t) { ... }

extern "C" int   foo_of_int(int t) { return foo(t); }

extern "C" char* foo_of_charp(char* p) { return foo(p); }

小结一下,C++的代码该调用重载就调用重载,该调用模板调用模板,没影响,但是C的代码想调用这两种函数的话,必须包装一下。

在C代码中访问C++的类和类的成员函数

Q:我们可以在C代码中访问C++的类吗?

A:或许我们可以在C中声明一个和C++很像的结构体,然后通过某种方式去调用里面的函数?

没错,这种方法是可行的,虽然这样做会给代码的可移植性、和维护上增加一些额外复杂的工作。比如我们C++代码中做了任何的改变,你必须检查一下我们的C代码,有可能也要改变。看下面的例子。

比如现在有一个C++的类:

class M {

public:

    virtual int foo(int);

    // ...

private:

    int i, j;

};

我们不能在我们的 C 代码中也添加一个 M 类,但是可以获得一个指向 M 类对象的指针,这很像我们在 C 中用标准输入输出操作文件对象。我们在 C++ 代码中可以像上面包装模板一样再包装一下类的成员函数,如下:
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }

C 中使用 M 类的如下:
struct M; /* you can supply only an incomplete declaration */

int call_M_foo(struct M*, int); /* declare the wrapper function */

int f(struct M* p, int j) /* now you can call M::foo */

    { return call_M_foo(p, j); }

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值