小阳同学嵌入式学习日记-extern “C“

目录

一、extern "C"是什么?

二、C++调用C语言编写的.so库

三、C引用C++中的全局函数

四、C++语言规则和C语言规则有什么不同?

五、extern的注意事项


一、extern "C"是什么?

        在C++中,extern "C"是一个指示符,用于告诉编译器按照C语言的规则对代码进行处理,而不是C++的规则。这在与C代码进行交互时非常有用,因为C和C++有不同的名称修饰和函数调用约定。

        具体来说,extern "C"用于声明C语言风格的函数接口,这意味着函数名称不会被C++的名称修饰机制修改,也就是不会进行函数名称的重命名(名称修饰)。这样做可以确保C++代码可以正确地调用C语言编写的函数,因为C++和C语言之间的函数调用约定可能不同。

例如,假设有一个C语言函数声明如下:

// C语言代码
int c_function(int arg);

如果在C++中包含这个C语言头文件,并使用extern "C"声明,那么C++编译器将不会修改函数名称:

// C++代码
extern "C" {
    #include "c_library.h"
}

int main() {
    int result = c_function(10);
    return 0;
}

 这样,编译器就不会将 c_function 的名称进行修改,从而确保正确调用C语言的函数。

二、C++调用C语言编写的.so库

        在C++中调用一个C语言编写的 .so(共享对象)库并不复杂,因为C++和C都可以使用C的函数调用约定。下面是一个简单的步骤:

1.包含头文件:首先,在C++代码中包含要使用的C语言库的头文件。

extern "C" {
    #include "your_c_library.h"
}

        使用 extern "C" 声明告诉编译器这些函数是用C语言编写的,而不是C++。这样,编译器就会使用C的函数调用约定来调用这些函数。

2.链接库文件:确保在链接阶段将C语言库的 .so 文件链接到您的C++代码中。 

g++ your_cpp_code.cpp -o your_program -lyour_c_library

         在这个例子中,-lyour_c_library 选项告诉编译器链接名为 libyour_c_library.so 的库文件。

3.调用C语言函数:现在您可以在C++代码中直接调用C语言函数。

int result = c_function_name(arguments);

         可以像调用任何其他函数一样调用C语言函数,只需使用其函数名和参数列表。

4.使用命名空间(可选):如果C语言库中有许多函数,您可以将它们放在C++的命名空间中,以防止与其他库发生命名冲突。

namespace MyCLibrary {
    extern "C" {
        #include "your_c_library.h"
    }
}

 然后,可以这样调用函数:

int result = MyCLibrary::c_function_name(arguments);

         这些步骤应该能够在C++代码中成功调用一个C语言编写的.so库。

三、C引用C++中的全局函数

        如果 C 代码需要引用 C++ 中的全局函数,而这些函数被声明为 extern "C",那么 C++ 的头文件中确实需要使用 extern "C" 来声明这些函数。

        假设有一个 C++ 头文件 functions.h,其中声明了一个全局函数,并且这个函数被用 extern "C" 修饰,以确保其名称在链接时按照 C 语言规则进行修饰,那么在 C 代码中包含这个头文件时,需要正确处理这个声明:

// functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#ifdef __cplusplus
extern "C" {
#endif

void globalFunction(); // 声明一个全局函数

#ifdef __cplusplus
}
#endif

#endif

 在 C++ 实现文件中实现这个函数,并在需要的时候包含这个头文件:

// functions.cpp

#include "functions.h"
#include <iostream>

// 实现全局函数
void globalFunction() {
    std::cout << "Hello from globalFunction() in C++!" << std::endl;
}

 在 C 代码中包含这个头文件,并调用这个函数:

// main.c

#include "functions.h"

int main() {
    // 调用全局函数
    globalFunction();
    return 0;
}

        这样,当 C 代码调用 globalFunction() 时,会按照 C 语言的规则进行链接,确保能够正确地调用 C++ 中的全局函数。 

        在这种情况下,C 可以使用 extern 关键字来引用 C++ 中的全局函数,但是如果 C++ 的全局函数被声明为 extern "C",那么在 C 代码中不需要使用 extern 关键字

        extern 关键字主要用于告诉编译器某个变量或函数是在别处定义的,而不是在当前文件中定义。当 C++ 的全局函数被声明为 extern "C" 时,这个函数的名称在链接时会按照 C 语言规则进行修饰,因此在 C 代码中可以直接引用这个函数而不需要使用 extern

举例来说,如果在 C++ 中有一个全局函数声明如下:

// functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#ifdef __cplusplus
extern "C" {
#endif

void globalFunction(); // 声明一个全局函数

#ifdef __cplusplus
}
#endif

#endif

         那么在 C 代码中可以直接调用 globalFunction(),而不需要使用 extern

// main.c

#include "functions.h"

int main() {
    // 调用全局函数
    globalFunction();
    return 0;
}

四、C++语言规则和C语言规则有什么不同?

         C++ 和 C 语言在许多方面有所不同,其中一些重要的区别包括面向对象编程、函数重载、命名空间和异常处理。下面是一些具体的示例说明:

 1.面向对象编程:

  • C++ 是一种面向对象的语言,支持类和对象的概念,可以使用类来组织数据和函数。例如:

// C++ 中的类定义和使用
class Car {
private:
    string brand;
    string model;
    int year;

public:
    Car(string b, string m, int y) : brand(b), model(m), year(y) {}
    void displayInfo() {
        cout << "Brand: " << brand << ", Model: " << model << ", Year: " << year << endl;
    }
};

int main() {
    Car myCar("Toyota", "Corolla", 2022);
    myCar.displayInfo();
    return 0;
}
  •  C 语言不支持类和对象的概念,因此无法进行面向对象编程。

 2.函数重载:

  • C++ 支持函数重载,允许在同一个作用域内定义多个同名函数,只要它们的参数列表不同即可。例如:

// C++ 中的函数重载
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

int main() {
    cout << add(5, 3) << endl;     // 输出 8
    cout << add(3.5, 2.5) << endl; // 输出 6
    return 0;
}
  •  C 语言不支持函数重载,因此同一作用域内不允许定义多个同名函数。

 3.命名空间:

  • C++ 引入了命名空间的概念,允许将变量、函数和类组织到命名空间中,以避免命名冲突。例如:

// C++ 中的命名空间
namespace Math {
    int add(int a, int b) {
        return a + b;
    }
}

int main() {
    cout << Math::add(5, 3) << endl; // 输出 8
    return 0;
}
  •  C 语言不支持命名空间,因此所有的全局变量和函数都处于同一个命名空间内。

4.异常处理

  • C++ 提供了异常处理机制,可以使用 try-catch 块来捕获和处理程序中的异常。例如:

// C++ 中的异常处理
int divide(int a, int b) {
    if (b == 0) {
        throw "Division by zero!";
    }
    return a / b;
}

int main() {
    try {
        int result = divide(10, 0); // 试图除以0,抛出异常
    } catch (const char* msg) {
        cerr << "Error: " << msg << endl; // 捕获异常并输出错误信息
    }
    return 0;
}
  • C 语言不支持内置的异常处理机制,通常通过返回特殊值或设置全局错误代码来处理错误。

五、extern的注意事项

        使用 extern 关键字时需要注意以下几点:

  1. 声明与定义的分离: extern 只是声明一个变量或函数,而不是定义它。因此,在使用 extern 声明时,需要确保在其他地方有对应的定义。

  2. 作用域问题: extern 声明的变量或函数具有全局作用域,可以在整个程序中访问。

  3. 变量声明: 对于变量的 extern 声明,只是告诉编译器该变量是在其他文件中定义的,而不是在当前文件中定义的。

  4. 函数声明: 对于函数的 extern 声明,通常用于引用其他文件中定义的函数。这种声明方式可以使得多个文件共享同一个函数定义,而不需要重复定义。

  5. 常量声明: 在 C++ 中,对于 extern 声明常量,必须使用 const 关键字。这样声明的常量是一个声明而非定义,编译器在编译时不会为它分配存储空间,而是将其作为一个标识符,用于在其他文件中访问已定义的常量。

  6. 注意链接问题: extern 声明的变量或函数在链接时需要确保有对应的定义,否则会导致链接错误。

做大做强,再创辉煌! 

  • 38
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值