一点背景:
我有一个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);
}