在 Qt 信号和槽函数中将固定大小的 Eigen 类型作为参数传递
pass fixed-size Eigen types as parameters in Qt signals and slots function
这是与 Qt 论坛重复的 post:Qt forum thread
我需要在 Qt 信号和槽函数中传递一个 fixed-size vectorizable Eigen types。
请注意,信号和相应的槽函数在需要 QueuedConnection 的不同线程中是 运行。因此,信号函数中传递的参数被复制。详情请看这个link
Qt 声明参数可以通过值或 const 引用传递,信号槽将根据连接类型 (QueuedConnection/DirectConnection) 决定是否需要复制。
但是,Eigen 声明 Eigen 对象必须通过引用传递,否则它是非法的或者程序可能会崩溃(在我的例子中:我遇到了对齐问题的编译错误)。有关更多详细信息,请参阅此处:link
如果我通过 const 引用传递 Eigen 对象并在信号槽的 connect() 之前使用 qRegisterMetaType() 注册 Eigen 对象,我也会遇到编译错误。错误看起来像:
__declspec(align(‘16’)) 的实际参数不会对齐
我还写了一个包装器 class,其中包含根据要求 here 的 Eigen 对象。不幸的是,同样的错误。
我的环境:Win7 64bit – VS2010 – Qt 5.3.1 – Eigen 3.2.4
有人在 Qt signals-slots 函数中将 Eigen 对象作为参数传递了吗?你是怎么做到的。
更新(添加 SSCCE):
如果你想克隆自己,我把它放在要点上:
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
};
编译错误:
2>ClCompile: 2> main.cpp
2>C:\Qt\Qt5.3.1.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.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.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.
非常感谢,
林
根据持续数年的错误讨论:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=83
他们在以下环境中测试 Eigen:
- MSVC9、MSVC10、MSVC11,在 x64 中 -> 有效(错误未显示)
- MSVC11 x32 -> 有效。
- MSVC9、MSVC10,在 x32 中 -> 失败。
作为解决方法,我将
#define EIGEN_DONT_ALIGN_STATICALLY
在任何包含 Eigen 之前 header。
代码现在可以编译并且 运行 正确。
这是与 Qt 论坛重复的 post:Qt forum thread
我需要在 Qt 信号和槽函数中传递一个 fixed-size vectorizable Eigen types。 请注意,信号和相应的槽函数在需要 QueuedConnection 的不同线程中是 运行。因此,信号函数中传递的参数被复制。详情请看这个link
Qt 声明参数可以通过值或 const 引用传递,信号槽将根据连接类型 (QueuedConnection/DirectConnection) 决定是否需要复制。
但是,Eigen 声明 Eigen 对象必须通过引用传递,否则它是非法的或者程序可能会崩溃(在我的例子中:我遇到了对齐问题的编译错误)。有关更多详细信息,请参阅此处:link
如果我通过 const 引用传递 Eigen 对象并在信号槽的 connect() 之前使用 qRegisterMetaType() 注册 Eigen 对象,我也会遇到编译错误。错误看起来像: __declspec(align(‘16’)) 的实际参数不会对齐
我还写了一个包装器 class,其中包含根据要求 here 的 Eigen 对象。不幸的是,同样的错误。
我的环境:Win7 64bit – VS2010 – Qt 5.3.1 – Eigen 3.2.4
有人在 Qt signals-slots 函数中将 Eigen 对象作为参数传递了吗?你是怎么做到的。
更新(添加 SSCCE): 如果你想克隆自己,我把它放在要点上: 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
};
编译错误:
2>ClCompile: 2> main.cpp 2>C:\Qt\Qt5.3.1.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.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.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.
非常感谢, 林
根据持续数年的错误讨论: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=83
他们在以下环境中测试 Eigen: - MSVC9、MSVC10、MSVC11,在 x64 中 -> 有效(错误未显示) - MSVC11 x32 -> 有效。 - MSVC9、MSVC10,在 x32 中 -> 失败。
作为解决方法,我将
#define EIGEN_DONT_ALIGN_STATICALLY
在任何包含 Eigen 之前 header。
代码现在可以编译并且 运行 正确。