一点背景:
我有一个C代码库,该库是较大系统(全部C)的一部分。对于C库的这一特定部分,必须创建一个GUI,使用户可以使用这些选项。对于GUI,我选择了QT,因为需要跨平台支持。
我将Eclipse和MinGW用作IDE和编译器(但我认为问题是语言而不是特定于编译器?)。

使用QT,我创建了一个小部件,其中包含指向用C实现的结构的指针,该指针包含指向执行C库逻辑的多个函数的指针。

//QTWidget.cpp
extern "C" {
#include "c-src/CLogic.h"
//extern char* textHelper;
}

QTWidget::QTWidget(QWidget *parent)
{
    //rtw is a struct that contains a function pointer to a member of QTWidget
    this->rtw.displayText = &QTWidget::displayText;
    this->clogic = CLogic_getInstance(&rtw);
}

//Public SLOT, connected to a button's clicked SIGNAL
void QTWidget::buttonClicked()
{
    this->clogic->buttonClicked();
}

void QTWidget::displayText(char *text, int position)
{
    //I've tried creating a QString from the char*, but this does not work at all.
    //ui.textItem->setText(textHelper);
    ui.textItem->setText(text);
}

当用户在GUI中按下按钮时,将调用QTWidget::buttonClicked()方法,该方法告诉C库执行某些操作。注意,CLogic结构以保存函数指针的结构RefToWidget的形式引用了QTWidget。
//CLogic.c
static CLogic instance;

void CLogic_buttonClicked()
{
    //I've tried several variants here, such as making a global
    //char* textHelper = "Hello World";
    //that is referenced by using the "extern" keyword in the CPP file above.
    instance.rtw->displayText("Hello World", 1);
}
CLogic* CLogic_getInstance(RefToWidget *rtw)
{
    instance.rtw = rtw;
    instance.buttonClicked = &CLogic_buttonClicked();
}

调试该程序时,我发现所有功能调用均按预期执行(当我按一个按钮时,调用QT插槽buttonClicked(),调用CLogic_buttonClicked(),按计划调用QTWidget::displayText() ,但是在最后一次调用中,参数无效。char *文本指向0x1并声称指向内存超出范围,而int位置看起来像某个随机数(未初始化)。

如何将这些数据从C传递到CPP?

编辑@Luccas Matteis:
#ifdef __cplusplus
#include "QTWidget.h"

extern "C" {
#endif

struct RefToWidget{
#ifdef __cplusplus
    void (QTWidget::*displayLine)(char* text, int lineNumber);
#else
    void (*displayLine)(char* text, int lineNumber);
#endif
};

typedef struct RefToWidget RefToWidget;
#ifdef __cplusplus
}
#endif

如上所述,函数调用的行为符合预期,但是数据没有“正确”传递(即使我看时,代码似乎有点...怪异...;)

最佳答案

您的问题不是将char *从C传递到C++,而是从C调用C++函数。我假设CLogic.c被编译为C库?如果不是,是否可以将其重命名为CLogic.cpp或使用编译器开关来强制将其编译为C++,即使它具有C文件扩展名?

如果要在C库/系统上使用C++ GUI,则需要使用适当的Model-View-Controller逻辑。这里的C++代码是 View 和 Controller ,而C代码是模型(据我所知,这是最好的)。您需要进行设置,以便设置并从模型中获取数据,但是模型从未像尝试那样调用 View 或 Controller 。

考虑一下您真正要做什么。如果只想在按下按钮时显示静态字符串,为什么要麻烦调用CLogic.c?如果要显示依赖于CLogic实例状态的字符串,请执行以下操作:

void QTWidget::buttonClicked()
{
    char *display_text = this->clogic->get_button_click_text();
    ui.textItem->setText(display_text);
}

10-05 22:04