1

我有一个 C++ 库,它有一个返回 a 的特定函数boost::any,它的值类型是enum在不同的包含库中定义的特定类型。这通常工作正常。

但是,当我从 Matlab mex 文件动态链接到我的库时,我的库typeid(the_enum_t)中制作的东西和调用者中制作的东西似乎不同,因为它不比较==. 由于我实际上正在使用flann,其版本基于boost::any执行检查type_info::==,这会使一切都中断。静态链接工作得很好,但这在这里有点痛苦,我真的宁愿让它工作。

我认为type_info::==应该跨图书馆边界始终如一地工作。这是否与 Matlab 如何从 mex 动态加载库有关?


这是一些重现此代码的代码(也可在此 gist中以易于下载的形式使用 makefile 获得)。

首先,定义枚举 ( flann) 的库的替身:

namespace library {
    enum the_enum_t { el_one, el_two, el_three };
}

现在我的图书馆的代理,stubby.hpp

#include <boost/any.hpp>
#include "the_enum.hpp"
boost::any the_function();

及其实施stubby.cpp

#include "stubby.hpp"
boost::any the_function() {
    return boost::any(library::el_two);
}

最后,测试代码,它是为独立而不是为 mex 文件test.cpp编译的:-DNO_MEX

#include "stubby.hpp"
#include <boost/any.hpp>

#ifdef NO_MEX
#include <cstdio>
using std::printf;
int main() {
#else
#include "mex.h"
void mexFunction(int nlhs, mxArray **plhs, int nrhs, const mxArray **prsh) {
#endif
    boost::any val_any = the_function();
    printf("%s (equal: %d)\n",
            val_any.type().name(),
            val_any.type() == typeid(library::the_enum_t));
}

我得到了预期的输出

N5flann17flann_algorithm_tE (equal: 1)

从每个

$ g++ -o test{,.cpp} -DNO_MEX libstubby.a && ./test      
$ g++ -o test{_s,.cpp} -DNO_MEX libstubby.so && ./test_s
$ ln -sf test{,_s}.cpp && mex test_s.cpp libstubby.a && matlab -r test

但是动态链接 mex 文件不起作用:

$ mex test.cpp libstubby.so && matlab -r test
N5flann17flann_algorithm_tE (equal: 0)

我看到同样的行为

  • Matlab R2011b 和 R2011a,OSX 10.7,苹果 gcc 4.2.1
  • Matlab R2011b,CentOS 5.7,gcc 4.1.2
  • Matlab R2010a,Ubuntu 11.04,gcc 4.4.5

奇怪的是,我本可以在几个月前发誓它可以工作,但也许我只是在测试方面做得不好。

显然我可以通过静态链接来解决这个问题。但是为什么会这样呢?它与 Matlab 加载 mex 文件及其库的方式有关吗?

4

1 回答 1

1

Boost 有一个解决这个问题的方法;见https://svn.boost.org/trac/boost/ticket/754

boost 可能无法启用解决方法。尝试-DBOOST_AUX_ANY_TYPE_ID_NAME根据该票证上的补丁传递编译器标志。

于 2012-07-16T18:35:43.860 回答