zoukankan      html  css  js  c++  java
  • C 程序与 C++ 程序之间的相互调用

    因为 C 编译器编译函数时不带参数的类型信息,只包含函数的符号名字。如 void foo( int x ) , C 编译器会将此函数编译成类似 _foo 的符号,C 链接器只要找到了调用函数的符号,就会认为链接成功。而 C++ 编译器为了实现函数重载,会在编译时带上函数的参数信息。如它可以把上面的函数编译成类似于 _foo_int 这样的符号。

    所以在 C++ 与 C 相互调用时,要用 extern "C" 加以声明。

    下面用两个示例实现它们之间的相互调用(没有优化代码,只是起示例作用)。

    C++ 调用 C 函数

    /* cfile.c */
    
    #include <stdio.h>
    
    void C_Func()
    {
    	puts("Hello, I'm C_Func");	
    }
    
    /* cppfile.cpp */
    
    #include <iostream>
    
    extern "C" void C_Func(void);
    
    int main()
    {
    	C_Func();
    
    	system("pause");
    	return 0;
    }
    

    C 调用 C++ 内类的成员函数

    /* cppfile.cpp */
    
    #include <iostream>
    #include "cpphfile.h"
    
    using namespace std;
    
    void Myclass::print()
    {
    	cout << "Hello, I'm print function." << endl;
    }
    
    /* cpphfile.h */
    
    #ifndef _CPPCLASS_H__
    #define _CPPCLASS_H__
    
    class Myclass{
    public:
    	void print();
    };
    
    #endif
    
    /* wrapper.cpp 这个文件实现调用 C++ 的接口*/
    
    #include "cpphfile.h"
    
    extern "C" {
    
    	struct wrapper_class{
    		Myclass w_class;
    	};
    
    	struct wrapper_class* get_object()
    	{
    		return new struct wrapper_class;
    	}
    
    	void call_cpp_print(struct wrapper_class* p)
    	{
    		p->w_class.print();
    	}
    
    }
    
    /* cfile.c */
    
    #include <stdio.h>
    
    struct wrapper_class *test;
    
    int main()
    {
    	/* 创建对象 */
    	test = get_object();
    
    	/* 调用 C++ 函数 */
    	call_cpp_print(test);
    	
    	system("pause");
    }
    

    小总结

    extern "C" 应该只能在 CPP 文件或被引入到 CPP 中的头文件内声明。

    通常应该这样使用 extern "C":

    #ifdef __cplusplus 
    extern "C" { 
    #endif
    
    /* your text */
    
    #ifdef __cplusplus 
    } 
    #endif
    

    C++ 编译器中已经定义了 __cplusplus 这个宏。

  • 相关阅读:
    vim的强大,vim设置和插件的使用,脱离windows才是王道
    [VS2013]如何闪开安装VS2013必须要有安装IE10的限制
    常用客户端实现逻辑
    开源控件ViewPagerIndicator学习
    常用设计模式
    主题演讲:未来新趋势电动车
    你最美好的年华
    一度总结
    android线程池ThreadPoolExecutor的理解
    Touch事件or手机卫士面试题整理回答(二)
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/9354387.html
Copyright © 2011-2022 走看看