How to call self made C function in Qt?
-
wrote on 25 Oct 2011, 05:09 last edited by
Hi, I need to use C to make a function and then be called in Qt. And I tried to compile the C funtion to be a static or dynamic lib first, then call it in Qt. But I failed.
Can anyone help to analyse the reason why it always tell me ' 'sum2' was not declared in this scope'. If I change the source code to call sleep(1), it can succeed. But why my static lib fails, although I set the path to the g++ correctly already?
Thanks!To generate the static lib:
@gcc -c sum.c
ar -rc libsum.a sum.o@The make under my scratchbox output is below: As you can see, I put the static lib path there '-I. libsum.a'
make
@g++ -c -pipe -O3 -g -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/targets/FREMANTLE_ARMEL/usr/share/qt4/mkspecs/linux-g++-gles2 -I. -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtCore -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtGui -I/targets/FREMANTLE_ARMEL/usr/include/qt4 -I. -I. -I. libsum.a -o mainwindow.o mainwindow.cpp
mainwindow.cpp: In member function 'int MainWindow::setValue(int)':
mainwindow.cpp:24: error: 'sum2' was not declared in this scope
mainwindow.cpp: At global scope:
mainwindow.cpp:20: warning: unused parameter 'duty_value'
make: *** [mainwindow.o] Error 1
@The C function for test is below. sum.c and sum.h
cat sum.c
@sum2(int a, int b)
{return a+b;}@cat sum.h
@int sum2(int a, int b);@The Qt cpp and header files are below.
[sbox-FREMANTLE_ARMEL: ~/LED_Driving] > cat mainwindow.cpp
@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timerUpDate()));
timer->start(20); //20ms one time
}void MainWindow::timerUpDate()
{
connect(ui->horizontalSlider, SIGNAL(valueChanged(int)),
this, SLOT(setValue(int)));
}int MainWindow::setValue(int duty_value)
{
// gpio(duty_value);
// sleep(1);
return sum2(8,7);
}MainWindow::~MainWindow()
{
delete ui;
}@cat mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();public slots:
int setValue(int);private:
Ui::MainWindow *ui;
void timerUpDate();
};#endif // MAINWINDOW_H@
-
wrote on 25 Oct 2011, 05:28 last edited by
Are you including your sum.h header file so that your C++ code knows about your function?
Also, take a look "here":http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html for some more important information you will need.
-
wrote on 25 Oct 2011, 06:44 last edited by
Yes, I tried to include sum.h in mainwindow.h but still failed and got below output of 'make'.
make
@> make
/usr/bin/uic mainwindow.ui -o ui_mainwindow.h
g++ -c -pipe -O3 -g -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/targets/FREMANTLE_ARMEL/usr/share/qt4/mkspecs/linux-g++-gles2 -I. -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtCore -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtGui -I/targets/FREMANTLE_ARMEL/usr/include/qt4 -I. -I. -o main.o main.cpp
g++ -c -pipe -O3 -g -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/targets/FREMANTLE_ARMEL/usr/share/qt4/mkspecs/linux-g++-gles2 -I. -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtCore -I/targets/FREMANTLE_ARMEL/usr/include/qt4/QtGui -I/targets/FREMANTLE_ARMEL/usr/include/qt4 -I. -I. -I. -L. libsum.a -o mainwindow.o mainwindow.cpp
mainwindow.cpp: In member function 'int MainWindow::setValue(int)':
mainwindow.cpp:26: error: 'sum2' was not declared in this scope
mainwindow.cpp: At global scope:
mainwindow.cpp:22: warning: unused parameter 'duty_value'
make: *** [mainwindow.o] Error 1
@And let's see another trial. With below program and the libsum.a, it can run normally without the header (sum.h) included.
cat testsum.c
@#include <stdio.h>int main()
{ printf("%d\n", sum2(8, 7));
return 0;
}@then compile
@> gcc testsum.c -I. libsum.a -o testsum@then run
@> ./testsum
15@So why this testsum.c C code can call the lib while the Qt code cannot call it?
-
wrote on 25 Oct 2011, 08:15 last edited by
[quote author="justforfun" date="1319519369"]
The C function for test is below. sum.c and sum.hcat sum.c
@sum2(int a, int b)
{return a+b;}@cat sum.h
@int sum2(int a, int b);@
[/quote]If this is all you have implemented in your files, it might be a little too minimalistic.
One should at least include the header file in the source file. So, this looks a little better:
@
#include "sum.h"int sum2(int a, int b)
{
return a+b;
}
@Note, that I have declared also the return type. You should have at least seen a number of warnings through compilation.
No, obviously you have not included sum.h in your code where you are using function sum2.
You may add the header in mainwindow.cpp
@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include "sum.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timerUpDate()));
timer->start(20); //20ms one time
}void MainWindow::timerUpDate()
{
connect(ui->horizontalSlider, SIGNAL(valueChanged(int)),
this, SLOT(setValue(int)));
}int MainWindow::setValue(int duty_value)
{
// gpio(duty_value);
// sleep(1);
return sum2(8,7);
}MainWindow::~MainWindow()
{
delete ui;
}
@I assume your code may be compilable now. However, I have not tried it.
The things, you are fighting with, are C/C++ basics. It would be probably more helpful for you to work through a C/C++ tutorial in more detail before you are digging into Qt.
-
wrote on 25 Oct 2011, 08:24 last edited by
Thank you for your reply!
Now the make output is below
@...
mainwindow.o: In functionMainWindow::setValue(int)': /home/maemo/LED_Driving/mainwindow.cpp:33: undefined reference to
sum2(int, int)'
collect2: ld returned 1 exit status
make: *** [LED_Driving] Error 1@In fact I know those points you mentioned, and I tried before this post. But the test result shows it is not as easy as it looks. I am still wondering how to solve it...
-
wrote on 25 Oct 2011, 08:59 last edited by
I think you should study the basics of C programming, namely how the compilation and linking processes work...
That undefined reference error means that the linker did not see a definition for that function (symbol). Are you sure you're linking against the object files that contain the implementation of sum2?
-
wrote on 25 Oct 2011, 09:03 last edited by
[quote author="mlong" date="1319520527"]Also, take a look "here":http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html for some more important information you will need.[/quote]
Have you read and followed what's written there? You usually cannot just link C and C++ code without any further preparations.
-
wrote on 25 Oct 2011, 16:20 last edited by
You need to use extern "C" when including C headers to C++. Usually you write your C headers (which you think might be used in C++ projects) like this:
[code]
#ifdef __cplusplus
extern "C" {
#endifint mySum(int a, int b);
...#ifdef __cplusplus
}
#endif
[/code]In general, mixing C and C++ is very easy. Just remember (1) using extern "C", (2) compiling C files with C (not C++) compilers. If you use C++ compiler, and want it to produce "C-style" libraries (which can be used by many different languages, e.g. C++ and Python), use extern "C" to use C-style naming convention. You find more information about this topic easily from Internet.
-
wrote on 26 Oct 2011, 09:14 last edited by
Thank you everyone! mkoskim, you are right. I succeeded with the method you mentioned. I will do some further test to learn more.
-
wrote on 16 Jul 2014, 00:01 last edited by
It shows the error before the file is not compiled.
Whenever we include any external header files in our source code, we have to compile it.
In this case, you need to add the source file to the .pro file like this:
----- .pro file-----------------------
@
SOURCES += main.cpp
mainwindow.cpp
cat.cHEADERS += mainwindow.h
FORMS += mainwindow.ui
@
Now try and compile the file.