C中如何调用C++函数?

前阵子被问及一个在C中如何调用C++函数的问题,当时简单回答是将函数用extern "C"声明,当被问及如何将类内成员函数声明时,一时语塞,后来网上查了下,网上有一翻译C++之父的文章可以作为解答,遂拿来Mark一下。

将 C++ 函数声明为``extern "C"''(在你的 C++ 代码里做这个声明),然后调用它(在你的 C 或者 C++ 代码里调用)。例如:

// C++ code:

extern "C" void f(int);

void f(int i)

{

// ...

}

然后,你可以这样使用 f():

/* C code: */

void f(int);

void cc(int i)

{

f(i);

/* ... */

}

当然,这招只适用于非成员函数。如果你想要在 C 里调用成员函数(包括虚函数),则需要提供一个简单的包装(wrapper)。例如:

// C++ code:

class C

{

// ...

virtual double f(int);

};

extern "C" double call_C_f(C* p, int i) // wrapper function

{

return p->f(i);

}

然后,你就可以这样调用 C::f():

/* C code: */

double call_C_f(struct C* p, int i);

void ccc(struct C* p, int i)

{

double d = call_C_f(p,i);

/* ... */

}

如果你想在 C 里调用重载函数,则必须提供不同名字的包装,这样才能被 C 代码调用。例如:

// C++ code:

void f(int);

void f(double);

extern "C" void f_i(int i) { f(i); }

extern "C" void f_d(double d) { f(d); }

然后,你可以这样使用每个重载的 f():

/* C code: */

void f_i(int);

void f_d(double);

void cccc(int i,double d)

{

f_i(i);

f_d(d);

/* ... */

}

注意,这些技巧也适用于在 C 里调用 C++ 类库,即使你不能(或者不想)修改 C++ 头文件。

【C/C++开发】C中调用C++函数的更多相关文章

  1. 【VS开发】MFC中调用C函数模块的解决方案

    [VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序 ...

  2. 在C#中调用Win32函数EnumWindows枚举所有窗口。

    原文 http://www.cnblogs.com/mfm11111/archive/2009/06/30/1514322.html 开发旺旺群发软件,难点及重要技术点分析(一) 一.        ...

  3. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  4. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  5. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

  6. C中调用Lua函数

    我们先来看一个简单的例子: lua_State* L = NULL; // 内部调用lua函数 double f(double x, double y) { double z; lua_getglob ...

  7. C++ 构造函数中调用虚函数

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...

  8. Smarty模板中调用PHP函数

    因为应用需要,要在Smarty中调用PHP函数,实现办法如下:模板 数据条数:{$data|count} 活动页面文件后缀:{$page|substr:'-3'} 特殊情况:{$page|str_re ...

  9. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  10. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

随机推荐

  1. zabbix的历史数据存储到elasticsearch中

    基本配置项 https://www.jianshu.com/p/bffca8128e8f 官方说这个实验性的功能支持es的版本是5.0.x - > 6.1.x,如果使用早期或更高版本的Elast ...

  2. Codeforces 1137F Matches Are Not a Child's Play [LCT]

    Codeforces 很好,通过这题对LCT的理解又深了一层. 思路 (有人说这是套路题,然而我没有见过/kk) 首先发现,删点可以从根那里往下删,非常难受,所以把权值最大的点提为根. 然后考虑\(x ...

  3. 《挑战30天C++入门极限》C++中类的多态与虚函数的使用

        C++中类的多态与虚函数的使用 类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持 ...

  4. Tkinter 之ProgressBar进度条标签

    一.参数说明 参数 作用 cursor 鼠标位于进度条内时的形状 length 进度条长度 maximum 进度条最大刻度值 mode  进度条的模式.有两种:‘determinate’和’indet ...

  5. 浅析python迭代器及生成器函数

    1. 什么是迭代协议? 迭代协议主要包括两方面的协议集,一种是迭代器协议,另一种是可迭代协议.对于迭代器协议来说,其要求迭代器对象在能够在迭代环境中一次产生一个结果.对于可迭代协议来说,就是一个对象序 ...

  6. fluent提供的边界条件解析【转载】

    转载自:http://chengkang8.blog.163.com/blog/static/6719535620113149552369/ 1. 速度入口边界条件 用于定义流动入口边界的速度和标量 ...

  7. JAVA的日期类DATE

    好记性不如烂笔头. 1:常见场景  字符串转时间格式,日期转换字符串(在前后端交互 json) 导入包(好像我的IDEA 不知道装了什么插件 会自动补齐提示) import java.text.Par ...

  8. QTextToSpeech Win7奔溃

    在linux下,它是调用speech-dispatcher.在其它不同的平台上,调用各自平台的TTS引擎.所以在使用的时候,要确保本地的TTS引擎是可用的. 本地TTS引擎不可用可能会在声明QText ...

  9. input type color

    <input type="color"> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input ...

  10. Java8中的日期时间类

    测试类: import java.time.*; import java.time.format.DateTimeFormatter; public class App { public static ...