1
votes

This is a duplicated post as the Qt forum: Qt forum thread

I need to pass a fixed-size vectorizable Eigen types in Qt signals and slots function. Note that the signals and the corresponding slots function is run in different threads which require QueuedConnection. Therefore, the parameters pass in the signal function are copied. Please see this link for details

The Qt states that the parameters can be passed by value or const reference and the signals-slots will decide if a copy is required based on the connection type (QueuedConnection/DirectConnection).

However, Eigen states that the Eigen object must be passed by reference otherwise it is illegal or the program may crash (in my case: I got compilation errors for the alignment issue). For more details please see here: link

If I passed the Eigen object by const reference and registered the Eigen object using qRegisterMetaType() before the connect() for signals-slots, I got compilation error as well. The error looks like: actual parameter with __declspec(align(‘16’)) won’t be aligned

I also wrote a wrapper class which contains the Eigen object according to the requirement here. Unfortunately, same error.

My environment: Win7 64bit – VS2010 – Qt 5.3.1 – Eigen 3.2.4

Has anyone passed Eigen object as parameter in the Qt signals-slots function? How did you do that.

UPDATE (Add SSCCE): I've put it on gist if you want to clone yourself: https://gist.github.com/f8af655a238ec136dbe9.git

// main.cpp
#include <QCoreApplication>
#include "A.h"
#include "B.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    A obj_a;
    B obj_b;

    qRegisterMetaType<eigen_wrapper>("eigen_wrapper");
    QObject::connect(&obj_a, &A::send, &obj_b, &B::receive);

    return a.exec();
}

// A.h
#pragma once

#include <QObject>
#include "eigen_wrapper.h"


class A : public QObject
{
    Q_OBJECT

private:
    eigen_wrapper eigen_object;

signals:
    // signal
    void send(const eigen_wrapper &);
};


// B.h
#pragma once
#include <QObject>
#include "eigen_wrapper.h"


class B : public QObject
{

    Q_OBJECT

private:
    eigen_wrapper eigen_object;

    public slots:

        inline void receive (const eigen_wrapper &s)
        {
            eigen_object = s;
        }
};


// eigen_wrapper.h
#pragma once
#include "Eigen/Dense"

class eigen_wrapper
{
    Eigen::Vector3f vec;
    Eigen::Quaternionf quat;

public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

Compilation error:

2>ClCompile: 2> main.cpp 2>C:\Qt\Qt5.3.1\5.3\msvc2010_opengl\include\QtCore/qobjectdefs_impl.h(573): error C2718: 'const eigen_wrapper': actual parameter with __declspec(align('16')) won't be aligned 2> C:\Qt\Qt5.3.1\5.3\msvc2010_opengl\include\QtCore/qobjectdefs_impl.h(588) : see reference to class template instantiation 'QtPrivate::AreArgumentsCompatible' being compiled 2>
with 2> [ 2> A1=eigen_wrapper, 2>
A2=eigen_wrapper 2> ] 2>
c:\qt\qt5.3.1\5.3\msvc2010_opengl\include\qtcore\qobject.h(228) : see reference to class template instantiation 'QtPrivate::CheckCompatibleArguments' being compiled 2>
with 2> [ 2> List1=QtPrivate::List, 2> List2=QtPrivate::List 2> ] 2> ..\main.cpp(14) : see reference to function template instantiation 'QMetaObject::Connection QObject::connect(const A *,Func1,const B ,Func2,Qt::ConnectionType)' being compiled 2> with 2> [ 2> Func1=void (__thiscall A:: )(const eigen_wrapper &), 2> Func2=void (__thiscall B::* )(const eigen_wrapper &) 2> ] 2> 2>Build FAILED.

Thanks very much, Lin

1
Post an SSCCE. If you need inspiration for how to write a short, single-file Qt project, look at any of my answers that have code in them :)Kuba hasn't forgotten Monica
@KubaOber Thanks for your suggestion, I have added the SSCCE which reproduces the compilation error.linzhang.robot
Note that even if you use a reference to avoid this problem, the static Qt arguments compatibility check attempts to remove the ref and thus fails to compile.Louen

1 Answers

0
votes

According to a bug discussion lasted few years: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=83

They testes the Eigen in the following environment: - MSVC9, MSVC10, MSVC11, in x64 -> Works (the bug doesn't show up) - MSVC11 x32 -> Works. - MSVC9, MSVC10, in x32 -> FAILS.

As a work around, I put

#define EIGEN_DONT_ALIGN_STATICALLY

before any include Eigen header.

The code now compile and run properly.