を返す特定の関数を備えた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
ただし、mexファイルを動的にリンクすることはできません。
$ 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ファイルとそのライブラリをロードする方法と関係がありますか?