Linux C进阶 —— 与C++互相调用

    本文介绍C、C++函数互相引用的方法,以及各类目标文件(含.o目标文件、.a静态库、.so动态库)在互调使用中的详细编译链接方法。本文使用arm的交叉编译工具链作为编译和链接工具。

1. C调用C++方法(asio为c++库)

示例源码树:

$ tree .
.
├── include
│ ├── asio
│ │ ├── *.hpp
│ └── asio.hpp
├── hello.cpp
├── hello.hpp
└── main.c

1.1 c++模块功能封装函数

//hello.cpp

#include <iostream> #include <asio.hpp> /* 将asio类功能封装成函数 */ #ifdef __cplusplus extern "C" { //使g++按c风格编码函数名符号 #endif int hello() { asio::io_context io; asio::steady_timer t(io, asio::chrono::seconds(5)); t.wait(); std::cout << "Hello, world!" << std::endl; return 0; }
#ifdef __cplusplus }
#endif
//hello.hpp

#ifndef __HELLO_HPP__
#define __HELLO_HPP__

#ifdef __cplusplus
extern "C" {  //c风格编码的函数符号
#endif

int hello(); 

#ifdef __cplusplus
}
#endif

#endif

1.2 C代码调用C++

//main.c 

#include "hello.hpp"

int main()
{
    hello();
    return 0;
}

1.3 C链接C++的三种方式

方法1: cpp模块编译成.o后与.c编译链接

$ arm-linux-g++  hello.cpp  -c  -o hello.o  -I../include  -DBOOST_DATE_TIME_NO_LIB     -DBOOST_REGEX_NO_LIB  --std=c++11
$ arm-linux-gcc -g main.c hello.o -o main -I./ -lstdc++ -lpthread

方法2: cpp模块生成so库与.c编译链接

$ arm-linux-g++  hello.cpp  -fpic -shared -o libhello.so  -I../include -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -lpthread -std=c++11
$ arm-linux-gcc main.c -lhello -L./ -o main  -I./

方法3: cpp模块生成静态库后与.c编译链接

$ arm-linux-g++  hello.cpp  -c  -o hello.o  -I../include -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB  --std=c++11
$ arm-linux-ar rcs libhello.a hello.o
$ arm-linux-gcc -g main.c libhello.a -o main -L./ -I./ -lstdc++ -lpthread 

2. C++调用C函数

示例源码树

$ tree .
.
├── include
│   ├── asio
│   │   ├── *.hpp
│   └── asio.hpp
└── libsrc
    ├── hello.c
    ├── hello.h
    └── main.cpp

2.1 C模块源码

//hello.c
#include<stdio.h> #ifdef __cplusplus extern "C"{ #endif void cpp_call_c() { printf("Hello C Function.\n"); return ; } #ifdef __cplusplus } #endif
//hello.h
#ifdef __cplusplus
extern "C"{
#endif
void cpp_call_c();
#ifdef __cplusplus
}
#endif

2.2 C++调用C函数源码

// main.cpp

#include <iostream>
#include <asio.hpp>
#include "hello.h"

int main()
{
    asio::io_context io;
    asio::steady_timer t(io, asio::chrono::seconds(5));
    t.wait();
    std::cout << "Hello, world!" << std::endl;
    cpp_call_c();

    return 0;
}

2.3 编译链接方法

方式1: c编译成.o文件后与cpp一起编译

$ arm-linux-gcc -c hello.c -o hello.o
$ arm-linux-g++ -g main.cpp hello.o -o main -I. -I../include  -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -lpthread -std=c++11

方式2:c模块编译成so库与cpp一起链接

$ arm-linux-gcc  hello.c -fpic -shared -o libhello.so
$ arm-linux-g++ -g main.cpp  -o main -lhello -L./  -I. -I../include  -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -lpthread -std=c++11

方式3: c模块编译成静态库后与cpp一起编译

$ arm-linux-gcc -c  hello.c  -o hello.o
$ arm-linux-ar rcs  libhello.a  hello.o
$ arm-linux-g++ -g main.cpp libhello.a -o main   -I. -I../include  -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -lpthread -std=c++11

 

posted @ 2024-05-30 20:10  云的边界  阅读(362)  评论(0)    收藏  举报