How to call self made C function in Qt?



  • 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_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    public slots:
    int setValue(int);

    private:
    Ui::MainWindow *ui;
    void timerUpDate();
    };

    #endif // MAINWINDOW_H@


  • Moderators

    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.



  • 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?


  • Moderators

    [quote author="justforfun" date="1319519369"]
    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);@
    [/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.



  • Thank you for your reply!

    Now the make output is below
    @...
    mainwindow.o: In function MainWindow::setValue(int)': /home/maemo/LED_Driving/mainwindow.cpp:33: undefined reference tosum2(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...



  • 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?



  • [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.



  • 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" {
    #endif

    int 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.



  • Thank you everyone! mkoskim, you are right. I succeeded with the method you mentioned. I will do some further test to learn more.



  • 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.c

    HEADERS += mainwindow.h

    FORMS += mainwindow.ui
    @


    Now try and compile the file.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.