1

を返す特定の関数を備えたC++ライブラリがありますboost::any。その値の型は、enum含まれている別のライブラリで特定に定義されています。これは通常は正常に機能します。

しかし、Matlab mexファイルから動的にライブラリにリンクすると、ライブラリtypeid(the_enum_t)で作成されたものと呼び出し元で作成されたもので、比較されないという点で異なるように見えます==。私は実際にを使用しているのでflann、そのバージョンはにboost::any基づいてチェックを実行しtype_info::==ます。これにより、すべてが壊れます。静的リンクは問題なく機能しますが、それはここでは一種の苦痛であり、どちらの方法でも機能させたいと思います。

type_info::==ライブラリの境界を越えて一貫して機能するはずだと思いました。これは、Matlabがmexからライブラリを動的にロードする方法と関係がありますか?


これを再現するためのコードをいくつか示します(この要点では、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

ただし、me​​xファイルを動的にリンクすることはできません。

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

私はこれと同じ振る舞いを

  • Matlab R2011bおよびR2011a、OSX 10.7、Apple 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を参照

ブーストが回避策を有効にできない可能性があります。-DBOOST_AUX_ANY_TYPE_ID_NAMEそのチケットのパッチごとにコンパイラ フラグを渡してみてください。

于 2012-07-16T18:35:43.860 に答える