zoukankan      html  css  js  c++  java
  • 【转载】C++中的extern C

    本文转自http://blogold.chinaunix.net/u/18517/showart_196363.html

    C++中的extern C


       本文主要讨论C++中extern C的使用。
       作者:tyc611, 2006-11-06


       在使用extern "C"声明时,有两种不同的形式:一是extern "C"后跟函数(或者变量)声明;另外就是extern "C"{函数(或变量)声明}。第一种形式(inline form)表示同时声明为外部连接和C风格连接;而第二种形式仅声明为C风格连接(并不附带外部声明)。例如:

    //第一种形式 
    extern "C" int foo;       //外部变量声明并且C风格连接
    extern "C" void bar();    //外部函数声明并且C风格连接,此时就不能为static

    //第二种形式
    extern "C" {
       int foo;               //C风格连接,并且定义变量(不是外部连接声明!)
       void bar();
    }

       所以当将第二种形式改写成如下形式时,两种形式才具有等价性:

    //第二种形式修改
    extern "C" {
       extern int foo;         //这儿的extern声明其作用对象为外部连接
       extern void bar();
    }

       对于有extern "C"声明的函数,其作用只是改变了函数的连接形式(采用C风格,即在目标文件中的符号名与函数名相同),并非改变函数的性质(也就是说被修饰的C++函数还可照常使用C++语言特性,与一般的C++函数除了多了个修饰之外,从外表上看并没有其它区别)。从如下示例程序中可以更清楚地看到这点:

    // A.h

    #ifndef MY_A_H
    #define MY_A_H

    #include <iostream>

    class A
    {
    public:
     void print()
     {
      std::cout<<"Message from class A"<<std::endl;
     }
    };

    #endif //MY_A_H

    ////////////////////////////////////////////////////

    // func.cpp

    #include "A.h"

    extern "C"
    void func(A& a)
    {
     int* p=new int[23];  // test new operator
     *p=1;

     a.print();

     delete [] p;
    }

    ////////////////////////////////////////////////
    // main.cpp

    #include "A.h"

    extern "C" void func(A& a);

    int main()
    {
     A a;
     func(a);

     return 0;
    }

       另外,标准中规定这种形式是非法的:
         extern "C" static void f(); // error
    因为extern "C"表明它是外部连接的,与static矛盾(多存储类型声明错误)。但在VC6.0和MinGW2.05上这样声明却没有错误,不知道为什么会这样。不过,在定义时:
         extern "C" static void f(){...} // error
    在VC6.0中没有编译错误,但会有连接错误(main中找不到func的定义);而MinGW2.05有编译错误(多个存储类型声明错误)。看来,MinGW工作得更好些。

       使用extern "C"的一个很重要的因素是关于从动态库里提取函数等问题的需要,见下面的参考文献[2]。


    参考文献:
    [1]ISO-IEC-14882-1998.pdf, 7.5
    [2]关于从动态库里提取对象:http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/C++-dlopen-mini-HOWTO.html#seealso

    -------------- Now, Or Never. --------------
  • 相关阅读:
    六种排序
    洛谷 P1879 [USACO06NOV]玉米田Corn Fields
    [USACO06NOV]玉米田Corn Fields
    c++位运算符 | & ^ ~ && ||,补码,反码
    Blockade(Bzoj1123)
    割点(Tarjan算法)【转载】
    子串
    生命是什么
    怎样说话才打动人
    自控力
  • 原文地址:https://www.cnblogs.com/levinkai/p/2140799.html
Copyright © 2011-2022 走看看