C和C++混合编程

我们知道很多系统底层的库都是由C语言写的,我们开发软件项目时,为了模块化的开发,也可能使用C语言写一些基础的函数库作为动态链接库加载到我们的程序中。这篇笔记介绍如何使用C语言和C++混合编程,尤其是如何使用C++调用C写的函数库。

在C++中调用C写的函数

func.c

int max(int a, int b) {
  if (a > b)
    return a;
  else
    return b;
}

func.h

#ifndef FUNC_H
#define FUNC_H

#ifdef __cplusplus
extern "C" {
#endif

int max(int a, int b);

#ifdef __cplusplus
}
#endif

#endif

main.cpp

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

int main() {
  int x = 1;
  int y = 2;

  std::cout << max(x, y) << std::endl;

  return 0;
}

编译和链接命令如下。

gcc -c func.c
g++ -c main.cpp
g++ func.o main.o -o main

注意头文件中我们使用了extern "C"这样的写法,这是因为在C++中,为了支持函数重载,默认编译后的函数名和代码中定义的函数名肯定是不一样的,这和C语言不同。如果不使用extern "C"就找不到函数定义的位置了。加上这个关键字,C++编译器会按照C语言的方式不改变原来的函数名,这样就能正常调用C语言中写的函数了。

此外我们还需要注意__cplusplus这个宏,通常C++编译器会默认定义这个宏,因此我们可以通过它来识别引用这个头文件的源代码,检查它使用的编译器是C编译器还是C++编译器。这种写法保证了C++可以调用头文件中的函数,C调用也不会因为编译器不认识extern "C"而出错。

在C++中调用C编写的动态链接库

调用动态链接库的道理和上面是完全一样的,代码无需更改,这次我们先把func.c编译成.so库,然后编译main.cpp时,链接这个库。

编译和链接命令如下。

gcc -shared -o libfunc.so func.c
g++ main.cpp -L. -lfunc -I. -o main

执行命令如下,注意这里要先指定下我们编写的共享库的路径。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./main

编译相关的内容可以参考C++/C语言基础/静态库和共享库相关章节。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap