extern “C“ 怎么使用? 函数前加 extern 是什么意思? 深度理解 C++ 与 C 代码之间的互操作性


一、extern “C” 怎么使用

介绍 extern “C”

我正在探讨如何在 C++ 中使用 extern "C",以防止名称修饰和实现与 C 的互操作性。这涉及到函数声明、头文件和链接等内容。

extern "C" 是 C++ 中用于指定使用 C 语言的链接方式(链接规范)的声明修饰符。它主要用于实现 C++ 与 C 代码之间的互操作性,避免由于 C++ 的名称修饰(Name Mangling)导致的链接错误。通过使用 extern "C",可以确保 C++ 编译器生成的函数名称与 C 语言的名称保持一致,从而实现两者之间的无缝调用。

1.1 为什么需要 extern "C"

C++ 支持函数重载和命名空间等特性,这导致编译器在生成符号时会进行名称修饰(Name Mangling),使得同名但参数不同的函数能够共存。而 C 语言不支持函数重载,编译器不会对函数名称进行修饰。因此,当需要在 C++ 中调用 C 函数或将 C++ 函数暴露给 C 时,名称修饰会导致链接错误。这时,extern "C" 就显得尤为重要。

1.2 extern "C" 的基本用法

1. 在 C++ 中调用 C 函数

假设有一个 C 语言编写的库,包含以下函数:

C 语言代码(example.c)

// example.c
#include <stdio.h>

void hello() {
   
   
    printf("Hello from C!\n");
}

C++ 代码(main.cpp)

// main.cpp
#include <iostream>

// 使用 extern "C" 声明 C 函数
extern "C" {
   
   
    void hello();
}

int main() {
   
   
    hello(); // 调用 C 函数
    return 0;
}

编译和链接

# 编译 C 代码
gcc -c example.c -o example.o

# 编译 C++ 代码
g++ -c main.cpp -o main.o

# 链接生成可执行文件
g++ main.o example.o -o my_program

运行 my_program 会输出:

Hello from C!
2. 在 C++ 中定义可以被 C 调用的函数

C++ 代码(library.cpp)

// library.cpp
#include <iostream>

extern "C" void greet(const char* name) {
   
   
    std::cout << "Hello, " << name << " from C++!" << std::endl;
}

C 语言代码(main.c)

// main.c
#include <stdio.h>

// 声明 C++ 函数
void greet(const char* name);

int main() {
   
   
    greet("C Programmer");
    return 0;
}

编译和链接

# 编译 C++ 代码
g++ -c library.cpp -o library.o

# 编译 C 代码
gcc -c main.c -o main.o

# 链接生成可执行文件
g++ main.o library.o -o my_program

运行 my_program 会输出:

Hello, C Programmer from C++!

1.3 在头文件中使用 extern "C"

为了方便 C++ 和 C 之间的互操作,通常会在头文件中使用条件编译来包含 extern "C",以确保在 C++ 编译器下使用 C 的链接规范,而在 C 编译器下不使用。

头文件示例(example.h)

// example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H

#ifdef __cplusplus
extern "C" {
   
   
#endif

void hello();
void greet(const char* name);

#ifdef __cplusplus
}
#endif

#endif // EXAMPLE_H

这样,无论是 C 还是 C++ 编译器包含此头文件,都能正确处理函数声明。

1.4 注意事项

  1. 仅用于函数声明extern "C" 主要用于函数的声明和定义,不适用于类、模板等 C++ 特有的特性。
  2. 名称修饰:使用 extern "C" 可以防止名称修饰,但需要确保函数的参数和返回类型在 C 和 C++ 中兼容。
  3. 内联函数:C++ 的内联函数不能被 extern "C" 修饰,因为 C 不支持内联函数。
  4. 变量声明:虽然可以使用 extern "C" 来声明变量,但需要小心处理全局变量的命名和初始化,确保与 C 代码的一致性。

1.5 更复杂的示例:C++ 类与 C 的互操作

由于 C 不支持类,通常通过 C++ 提供的 C 接口来操作类对象。这涉及到封装类指针并通过 C 接口进行操作。

C++ 类(MyClass.h 和 MyClass.cpp)

// MyClass.h
#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值