• C/C++语言补缺 宏- extern "C"-C/C++互调


    1. 宏中的#

    宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号。

    如定义好#define STRING(x) #x之后,下面二条语句就等价。

           char *pChar = "hello";  ==  char *pChar = STRING(hello);

    还有一个#@是加单引号(Charizing Operator)

    #define makechar(x)  #@x; ==  char ch = makechar(b);与char ch = 'b';等价。

    注意宏中遇到###时就不会再展开宏中嵌套的宏了。

    比如使用char *pChar =STRING(__FILE__);虽然__FILE__本身也是一个宏,但编译器不会展开它,所以pChar将指向"__FILE__"

    因此要加一个中间转换宏,先将__FILE__解析成你希望的字符串。

    #define _STRING(x) #x

    #define STRING(x) _STRING(x)

    再调用下面语句将输出带""的源文件路径

    char* pChar = STRING(__FILE__);

    printf("%s %s ", pChar, __FILE__);

    2.  宏中的##

    ##的功能:拼接符号(Token-pasting operator)。

    eg. #define paster( n ) printf( "token"#n" = %d ", token##n )

          int token9 = 100;

    再调用  paster(9);宏展开后token##n直接合并变成了token9。整个语句变成了 printf( "token""9"" = %d", token9 );

    在C语言中字符串中的二个相连的双引号会被自动忽略,于是上句等同于 printf("token9 = %d", token9);。

    即输出token9 = 100.

    3. extern "C"

    extern "C"的真实目的是实现类C和C++的混合编程。在C++源文件中的语句前面加上extern "C",表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约,但仍然要遵守C++的类型检测、参数转换规则。这样在类C的代码中就可以调用C++的函数/变量等。(注:类C,代表的是跟C语言的编译和连接方式一致的所有语言)

    4. C++中调用C的代码

    假设一个C的头文件cHeader.h中包含一个函数print(int i),为了在C++中能够调用它,必须要加上extern关键字(原因在extern关键字那节已经介绍)。它的代码如下:

    1
    2
    3
    4
    5
    6
    #ifndef C_HEADER
    #define C_HEADER
     
    extern void print(int i);
     
    #endif C_HEADER

    相对应的实现文件为cHeader.c的代码为:

    1
    2
    3
    4
    5
    6
    #include <stdio.h>
    #include "cHeader.h"
    void print(int i)
    {
        printf("cHeader %d ",i);
    }

    现在C++的代码文件C++.cpp中引用C中的print(int i)函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    extern "C"{
    #include "cHeader.h"
    }
     
    int main(int argc,char** argv)
    {
        print(3);
        return 0;
    }

    5. C中调用C++的代码

    现在换成在C中调用C++的代码,这与在C++中调用C的代码有所不同。如下在cppHeader.h头文件中定义了下面的代码:

    1
    2
    3
    4
    5
    6
    #ifndef CPP_HEADER
    #define CPP_HEADER
     
    extern "C" void print(int i);
     
    #endif CPP_HEADER

    相应的实现文件cppHeader.cpp文件中代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    #include "cppHeader.h"
     
    #include <iostream>
    using namespace std;
    void print(int i)
    {
        cout<<"cppHeader "<<i<<endl;
    }

    在C的代码文件c.c中调用print函数:

    1
    2
    3
    4
    5
    6
    extern void print(int i);
    int main(int argc,char** argv)
    {
        print(3);
        return 0;
    }

    注意在C的代码文件中直接#include "cppHeader.h"头文件,编译出错。而且如果不加extern int print(int i)编译也会出错

  • 相关阅读:
    php openssl 加密解密
    PHP中进制之间的互相转换
    零基础学习FFMPEG
    git 强制更新本地和强制提交覆盖
    mysql 不常用备忘
    mysql <=> null 问题
    GD库imagettftext中文乱码的问题
    flex布局设置width无效
    下拉菜单css
    swagger:API在线文档自动生成框架
  • 原文地址:https://www.cnblogs.com/xiaoxxy/p/3444430.html
Copyright © 2020-2023  润新知