首页 > 系统相关 >Linux C进阶 —— 与C++互相调用

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

时间:2024-05-30 20:10:38浏览次数:15  
标签:include 进阶 linux C++ arm Linux cpp main hello

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

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

示例源码树:

$ tree .
.
├── include
│ ├── asio
│ │ ├── *.hpp
│ └── asio.hpp
└── libsrc
├── CMakeLists.txt
├── 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
    ├── CMakeLists.txt
    ├── 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

 

标签:include,进阶,linux,C++,arm,Linux,cpp,main,hello
From: https://www.cnblogs.com/rtthread/p/18223144

相关文章

  • c++结构体解决复数辐角问题
     结构体相关知识及运行代码(来自发发老师)/*ch10_structs.cc介绍:这里解释了结构体的使用方法。包括:(1)定义和初始化。(2)赋值。(3)结构体和数组一起使用。注意数据成员和函数成员的访问。(4)结构体和向量一起使用。(5)结构体和函数。*/#include<iostream>......
  • 【c++基础(五)】内存管理--new
    1.前言在C语言中,有四个内存管理函数:malloc,calloc,realloc和free但是使用起来他们却是非常的不方便:int*p1=(int*)malloc(sizeof(int)*n);int*p2=(int*)calloc(4,sizeof(int));int*p3=(int*)realloc(p2,sizeof(int)*10);同时这里也会出现一个问题,malloc不会进......
  • 【c++基础(四)】类和对象下--初始化列表等概念
    1.前言类和对象到这里基本已经接近尾声,本篇文章主要介绍一些与类和对象有关的相关细节,在后续使用类和对象中也有可能用的到。本章重点:本篇文章重点讲解初始化列表,友元,匿名对象和类中的static成员,以及类中的内部类的概念。 2.初始化列表 在谈论初始化列表之前就要再次......
  • 【linux】开机调用python脚本
    linux中,可以使用crontab设置开机自动调用crontab的安装在前面文章里写过了,不再重复首先,还是进入crontab配置文件crontab-e进入之后,跟其他定时任务不同,只需要在时间配置那里用@rebooot这类之后的两个文件的配置分别是python的执行文件和需要调用的python脚本位置,还是......
  • linux 定时执行shell、python脚本
    在linux里设置定时执行一般是用crontab,如果没有的话,可以先安装:安装查看是否安装cron-v#对于基于Debian的系统(如Ubuntu)sudoapt-getinstallcron#对于基于RedHat的系统(如CentOS)sudoyuminstallcronie启动cron服务:#对于基于Systemd的系统sudosystemctlstart......
  • 区间和(C++)
    题目描述】给定一个全部为零的数列,规定有两种操作,一是修改某个元素,二是求区间的连续和。【输入】输入数据第一行包含两个正整数n,m(n≤100000,m≤500000) ,以下是m 行,每行有三个正整数k,a,b (k=0 或1,a,b≤n ).k=0 时表示将a 处数字加上b ,k=1 时表示询问区间[a,b......
  • Java面试进阶指南:高级问题与解答精粹(一)
    Java面试问题及答案1.什么是Java内存模型(JMM)?它的作用是什么?答案:Java内存模型(JMM)是一个抽象的概念,它定义了Java程序中各种变量(线程共享变量)的访问规则,以及在并发环境下如何保证这些变量的可见性、原子性和有序性。JMM的作用是确保在并发编程中,不同线程之间对共享变量的操......
  • Java面试进阶指南:高级问题与解答精粹(二)
    Java面试问题及答案1.什么是Java内存模型(JMM)?请简述它的作用。答案:Java内存模型(JMM)是一个抽象的概念,它定义了Java程序中各种变量(线程共享变量)的访问规则,以及在并发环境下如何保证数据的一致性。JMM规定了线程如何与主内存(所有线程共享的内存)交互,以及如何通过工作内存(每个......
  • Java进阶指南:高级面试问题与精辟解答(一)
    Java面试问题及答案1.请解释什么是Java内存模型(JMM)?它在并发编程中扮演什么角色?答案:Java内存模型(JMM)是一个抽象的内存模型,它定义了Java程序中变量的访问规则,以及在并发环境下如何保证内存操作的原子性、可见性和有序性。JMM确保了在多线程环境下,不同线程间对共享变量的......
  • Java进阶指南:高级面试问题与精辟解答(三)
    Java面试问题及答案1.什么是Java中的多态性?答案:多态性是Java中的一个重要特性,它允许一个引用类型可以指向多种实际类型的对象,并根据对象的实际类型调用相应的方法。多态性主要通过方法重载(静态多态)和方法重写(动态多态)来实现。方法重载发生在编译时,而方法重写发生在运行......