Using QtConcurrent::map() with pointer to non-static member function



  • I have a linking problem when trying to use map, probably something is wrong with how I am wrapping objects/functions.

    I think some sample code is the best way to explain this case.

    @
    // class that contains data and parameters
    class workItem;

    // wrapper for pointer to member
    struct addWrapper {
    MainProgram *instance;
    addWrapper(MainProgram *prog) : instance(prog) {}
    void operator()(workItem &item) {
    instance->processItem(item);
    }
    };

    // non-static member function that I desire to process concurrently
    MainProgram::processItem(workItem &item);

    // function that uses concurrency to process many workItems
    MainProgram::someFunction()
    {
    // Make a list of work to process
    QList<workItem> schedule;
    ...

    addWrapper wrapper(this);
    QFuture<void> result = QtConcurrent::map(schedule, wrapper);
    

    }
    @

    When I compile, this is the output:
    @
    Undefined symbols for architecture x86_64:
    "QtConcurrent::BlockSizeManager::timeAfterUser()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::BlockSizeManager::timeBeforeUser()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::BlockSizeManager::blockSize()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::BlockSizeManager::BlockSizeManager(int)", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::isCanceled()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::startThread()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::whileThreadFunction() in mainprogram.o
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::waitForResume()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::whileThreadFunction() in mainprogram.o
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::setProgressRange(int, int)", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::start() in mainprogram.o
    virtual thunk to QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::start()in mainprogram.o
    "QtConcurrent::ThreadEngineBase::setProgressValue(int)", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::forThreadFunction() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::acquireBarrierSemaphore()", referenced from:
    QtConcurrent::ThreadEngine<void>::startAsynchronously() in mainprogram.o
    "QtConcurrent::ThreadEngineBase::isProgressReportingEnabled()", referenced from:
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::start() in mainprogram.o
    virtual thunk to QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::start()in mainprogram.o
    "QtConcurrent::ThreadEngineBase::run()", referenced from:
    vtable for QtConcurrent::ThreadEngine<void>in mainprogram.o
    vtable for QtConcurrent::IterateKernel<QList<workItem>::iterator, void>in mainprogram.o
    construction vtable for QtConcurrent::ThreadEngine<void>-in-QtConcurrent::IterateKernel<QList<workItem>::iterator, void>in mainprogram.o
    vtable for QtConcurrent::MapKernel<QList<workItem>::iterator, addWrapper> in mainprogram.o
    construction vtable for QtConcurrent::IterateKernel<QList<workItem>::iterator, void>-in-QtConcurrent::MapKernel<QList<workItem>::iterator, addWrapper>in mainprogram.o
    construction vtable for QtConcurrent::ThreadEngine<void>-in-QtConcurrent::MapKernel<QList<workItem>::iterator, addWrapper>in mainprogram.o
    "QtConcurrent::ThreadEngineBase::ThreadEngineBase()", referenced from:
    QFuture<void> QtConcurrent::map<QList<workItem>, addWrapper>(QList<workItem>&, addWrapper)in mainprogram.o
    "QtConcurrent::ThreadEngineBase::~ThreadEngineBase()", referenced from:
    virtual thunk to QtConcurrent::ThreadEngine<void>::~ThreadEngine()in mainprogram.o
    QtConcurrent::ThreadEngine<void>::~ThreadEngine()in mainprogram.o
    QtConcurrent::ThreadEngine<void>::~ThreadEngine()in mainprogram.o
    virtual thunk to QtConcurrent::ThreadEngine<void>::~ThreadEngine()in mainprogram.o
    virtual thunk to QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::~IterateKernel()in mainprogram.o
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::~IterateKernel()in mainprogram.o
    QtConcurrent::IterateKernel<QList<workItem>::iterator, void>::~IterateKernel()in mainprogram.o
    ...
    "typeinfo for QtConcurrent::ThreadEngineBase", referenced from:
    typeinfo for QtConcurrent::ThreadEngine<void>in mainprogram.o
    ld: symbol(s) not found for architecture x86_64
    collect2: ld returned 1 exit status
    @

    This is Qt 5.0.2 on MacOS X 10.8.3.

    Any help will be appreciated.

    Thanks



  • Everything seems to be OK with your wrapper. Have you added Qt5Concurrent library into linker options?

    However, there is a different problem, not connected with linker errors: you pass local 'schedule' to asynchronous 'map' as reference, but I don't see you wait for the computation finish. This way 'schedule' could go out of the scope during computation and you would get crash.



  • I'm not seeing QtConcurrent framework when linking.

    I thought QtConcurrent was part of QtCore.
    How do I add it to my .pro file ?



  • OK, so I did an experiment and you need QT += concurrent

    Thanks for spotting the error with schedule. I was hoping that map() was going to copy each object in the list... wishful thinking.


Log in to reply
 

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