2012-07-13 2 views
1

boost::any을 반환하는 특정 함수를 가진 C++ 라이브러리가 있습니다. 그 값 유형은 다른 포함 라이브러리에 정의 된 enum입니다. 이것은 정상적으로 잘 작동합니다.열거 형의 typeid가 matlab mex 파일에 동적으로 링크되어있을 때 변경됨

그러나 Matlab mex 파일에서 내 라이브러리에 동적으로 링크하면 typeid(the_enum_t)은 내 라이브러리와 호출자가 만든 라이브러리의 내용이 달라서 ==과 비교되지 않습니다. 실제로 flann 버전을 사용하고 있기 때문에 boost::any 버전은 type_info::==을 기반으로 한 검사를 수행하므로이 모든 작업이 중단됩니다. 정적 연결은 잘 작동하지만 여기에는 다소 고통 스러울뿐입니다.

나는 type_info::==이 라이브러리 경계에서 일관되게 작동한다고 생각 했었습니다. 이것은 Matlab이 mex에서 동적으로 라이브러리를로드하는 방법과 관련이 있습니까?


여기 ( this gist에, 메이크와 쉬운 다운로드 형태로도 가능)이 재현하는 일부 코드입니다.

첫째, 독립의 라이브러리에 대한 열거 (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 파일을 -DNO_MEX로 컴파일 59,:

#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)); 
} 

나는

$ 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 

각에서 예상되는 출력

N5flann17flann_algorithm_tE (equal: 1) 

을 얻을 그러나 동적으로 연결 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, 우분투 11.04, gcc 4.4.5

이상한 일은 내가 몇 달 전에 작동했다고 맹세 할 수 있었지만 어쩌면 테스트를 잘못한 것일 수도 있습니다.

분명히 정적 링크를 통해이 문제를 해결할 수 있습니다. 그러나 이것이 왜 일어나는 것입니까? MATLAB이 mex 파일과 라이브러리를로드하는 방식과 관련이 있습니까?

답변

1

부스트가이 문제의 해결 방법이 있습니다. https://svn.boost.org/trac/boost/ticket/754

해결 방법을 사용할 수 없을 가능성이 있습니다. 해당 티켓의 패치 당 컴파일러 플래그 -DBOOST_AUX_ANY_TYPE_ID_NAME을 전달하십시오.

+0

감사합니다. Boost.Any는 실제로 이미 작동했지만,'type_info'만으로 테스트를했기 때문에 임시 해결책을 찾지 못했습니다. 'flann :: any'는 그 해결 방법을 포함하지 않고 실제로 충돌을 야기했기 때문에 테스트 코드를 너무 단순화했습니다. – Dougal