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.