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!!
  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/pingge/p/3155289.html
Copyright © 2011-2022 走看看