zoukankan      html  css  js  c++  java
  • DLL模块:extern "C"的简单解析

    1.揭密extern "C"

    extern "C"包含双重含义,从字面上即可得到:首先,被它修饰的目标是 "extern”的;其次,被它修饰的目标是 "C”的。
    首先来看一下 "extern”的含义
    a.在一个文件内,如果外部变量不在文件的开头定义,其有效范围只限定在定义到文件的结束处。如果在定义前需要引用该变量,则要在引用之前用关键字 "extern” 对该变量做“外部变量声明”,表示该变量是一个已经定义的外部变量。有个这个声明,就可以从声明处起合理地使用该变量了。"extern”起到了扩展作用域的作用。

    "C”的含义:(extern “C”)
    C++通过函数参数的不同类型支持重载机制,编译器根据参数为每个重载函数产生不同的内部标识符。例如编译器为void Eat(Beef …);void Eat(Fish …);void Eat(Chicken …);三个Eat 函数产生象_eat_beef、_eat_fish、_eat_chicken 之类的内部标识符(不同的编译器可能产生不同风格的内部标识符)。
    如果 C++程序要调用已经被编译后的C 函数,该怎么办?
    假设某个 C 函数的声明如下:

    1 void foo(int x, int y);

    该函数被C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字用来支持函数重载和类型安全连接。由于编译后的名字不同,C++程序不能直接调用C 函数。C++提供了一个C连接交换指定符号extern“C”来解决这个问题。
    例如:

     1 extern “C”
     2 {
     3 void foo(int x, int y);
     4// 其它函数
     5 }
     6 或者写成
     7 extern “C”
     8 {
     9 #include “myheader.h”
    10// 其它C 头文件
    11 }

    这就告诉C++编译译器,函数foo 是个C 连接,应该到库中找名字_foo 而不是找_foo_int_int。C++编译器开发商已经对C 标准库的头文件作了extern“C”处理,所以我们可以用#include 直接引用这些头文件。

    2.extern "C"程序实例

    假设有C文件:

    1 //c.h
    2 #ifndef _C_H_
    3 #define _C_H_
    4 
    5 extern int add(int x, int y);
    6 
    7 #endif
    1 //c.c
    2 int add(int x, int y)
    3 {
    4     return x+y;
    5 }
    1 //cplusplus.cpp
    2 #include <iostream>
    3 #include "c.h"
    4 using namespace std;
    5 void main()
    6 {
    7     add(1, 0);
    8     system("Pause");
    9 }

    产生错误:无法解析的外部符号 "int __cdecl add(int,int)" (?add@@YAHHH@Z),该符号在函数 _main 中被引用
    为了解决这个问题,我们需要使用extern "C"。改写C文件

     1 //c.h
     2 #ifndef _C_H_
     3 #define _C_H_
     4 
     5 #ifdef __cplusplus
     6 extern "C" {
     7 #endif
     8 
     9 extern int add(int x, int y);
    10 
    11 #ifdef __cplusplus
    12 }
    13 #endif
    14 
    15 #endif

    文件为*.c,__cplusplus没有被定义,extern "C" {}这时没有生效,对于C语言只是extern int add(int, int);而编译c++源文件,__cplusplus被定义,对于C++他看到的是extern "C" {extern int add(int, int);},编译器就会知道add(1, 0)调用的是C连接。
    最后:很多DLL的生成文件(XXX.c)中常出现extern "C" ,windows采用C语言编译创建dll,C程序可以正确调用DLL,而当用户使用C++调用DLL时,extern "C" {}就起作用了。

    ——现在的努力是为了小时候吹过的牛B!!
  • 相关阅读:
    【python cookbook学习笔记】给字典增加一个条目
    UI设计星级评价
    弱引用和循环引用
    lua数据类型
    lua虚拟机笔记
    c++对象模型笔记
    使树控件方向键无效
    实现CListCtrl自定义行高
    创建对话框时常用配置
    C++格式化输出总结
  • 原文地址:https://www.cnblogs.com/pingge/p/3155289.html
Copyright © 2011-2022 走看看