赞
踩
作者 | 将狼才鲸 |
---|---|
创建日期 | 2022-03-31 |
C语言中想调用C++中的方法,或者使用C++类中的数据,有三种方法:
一是将C++编译成动态库供C语言中调用;
二是使用Makefile 将C++和C分别用g++和gcc编译成.o,再在链接的时候实现C语言找到C++的方法入口进行调用;
三是C++调用C语言的一个函数将自己的方法通过回调函数的方式注册进C语言模块,C语言模块自己择机在需要的时候进行调用。
我觉得第三种使用回调函数的方法最好用,也方便单步调试,这里给出用Qt实现的一个例子。
Gitee工程源码地址:t_gui_simple2complex/ source / 005_Qt_with_C_language /
CSDN文章阅读地址:
#include "mainwindow.h" #include "ui_mainwindow.h" #include "cppmodule.h" #include "c_module.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { // 注册你要在C语言中调用的C++类 // 该类构造函数中已将方法注册进C语言中 cppmodule cppm; // C语言直接调用C++中的方法 c_module_process(); ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
#include <QDebug> #include "cppmodule.h" #include "c_module.h" cppmodule::cppmodule() { data1 = 1; data2 = 2; data3 = 3; // C++类将方法和数据注册进C语言模块,供C语言模块在需要的时候调用 c_module_init((void *)print1, (void *)print2, data1, data2, data3); } int cppmodule::print1() { qDebug("c++ print1"); return 0; } int cppmodule::print2() { qDebug("c++ print2"); return 0; }
#ifndef CPPMODULE_H #define CPPMODULE_H class cppmodule { public: cppmodule(); static int print1(); static int print2(); private: int data1; int data2; int data3; }; #endif // CPPMODULE_H
/** * \brief 如果不使用C++动态库,C源码中不能调用C++的内容,只能使用回调函数 */ #include <stdio.h> #define NULL ((void *)0) typedef int (*pfunc)(void); pfunc cppprint1 = NULL, cppprint2 = NULL; int cppdata1, cppdata2, cppdata3; extern int c_module_init(void *func1, void *func2, int data1, int data2, int data3) { if (func1) cppprint1 = func1; if (func2) cppprint2 = func2; cppdata1 = data1; cppdata2 = data2; cppdata3 = data3; // 测试g++编译C源码时是否支持GNU C的进阶关键字,如typeof printf("C++ callback to C module, data size: %d\n", sizeof(typeof(cppdata1))); return 0; } int c_module_process() { printf("C++ Class data1~3: %d, %d, %d\n", cppdata1, cppdata2, cppdata3); if (cppprint1) cppprint1(); if (cppprint2) cppprint2(); return 0; }
#ifndef C_MODULE_H #define C_MODULE_H #ifdef __cplusplus extern "C" { #endif // 供C++中调用,将回调函数注册进本C语言模块 extern int c_module_init(void *func1, void *func2, int data1, int data2, int data3); // C语言模块自己择机执行C++已注册进来的方法 extern int c_module_process(); #ifdef __cplusplus } #endif #endif // C_MODULE_H
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ c_module.c \ cppmodule.cpp \ main.cpp \ mainwindow.cpp HEADERS += \ c_module.h \ cppmodule.h \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"/> <widget class="QMenuBar" name="menubar"/> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
参考网址:
极简式从C调用C++类方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。