typeid of enum changing when dynamically linked in matlab mex file
===

I'm using [flann](https://github.com/mariusmuja/flann/) in a C++ library of mine. That library includes a [function called `npdivs::index_params_from_str`](https://github.com/dougalsutherland/np-divs/blob/master/np-divs/div_params.cpp#L46) that returns a `flann::IndexParams`, which is a typedef to `std::map<std::string, flann::any>`; `flann::any` is [basically just `boost::any`](https://github.com/mariusmuja/flann/blob/master/src/cpp/flann/util/any.h).

The relevant key in the map for now is `"algorithm"`, whose value is from the enum [`flann_algorithm_t`](https://github.com/mariusmuja/flann/blob/master/src/cpp/flann/defines.h#L96).

In normal situations, everything works fine. But when I link to my library dynamically from a Matlab mex file, `typeid(flann_algorithm_t)` seems to be different for the things made in the function call and elsewhere, which makes `flann::any` complain, and so I can't make my flann indices. Static linking works fine.

<hr />

Here's some code to reproduce it. First, a stand-in for the library, `stubby.hpp`:

    #include <string>
    #include <flann/flann.hpp>
    namespace npdivs {
        flann::IndexParams index_params_from_str(const std::string &spec);
    }

And its implementation `stubby.cpp`:

    #include "stubby.hpp"
    #include <stdexcept>
    namespace npdivs {
        flann::IndexParams index_params_from_str(const std::string &spec) {
            // even though this looks like object slicing, it's not, because all
            // these subclasses do is initialize some key/val pairs in their
            // constructors
            if (spec == "linear" || spec == "brute") {
                flann::LinearIndexParams ps;
                return ps;
            } else if (spec == "kdtree" || spec == "kd") {
                flann::KDTreeSingleIndexParams ps;
                return ps;
            } else {
                throw(std::domain_error("unknown index type " + spec));
            }
        }
    }

Test code `test.cpp`, which is compiled with `-DNO_MEX` for a standalone and not for a mex file:

    #include <flann/flann.hpp>
    #include "stubby.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
        typedef flann::flann_algorithm_t algo_t;
    
        flann::IndexParams index_params = npdivs::index_params_from_str("kdtree");
        flann::any algo_any = index_params["algorithm"];
        printf("%s (equal: %d)\n", algo_any.type().name(), algo_any.has_type<algo_t>());

        algo_t algo = algo_any.cast<algo_t>();
        printf("%d\n", algo);
    }

I get the expected output

    N5flann17flann_algorithm_tE (equal: 1)
    4

from each of

    $ g++ -o test{,.cpp} -DNO_MEX libstubby.a && ./test      
    $ g++ -o test{,.cpp} -DNO_MEX libstubby.dylib && ./test       
    $ mex test.cpp libstubby.a -I/usr/local/include && matlab -r test

But dynamically linking a mex file doesn't work:

    $ mex test.cpp libstubby.dylib -I/usr/local/include && matlab -r test
    # Matlab header for R2011b maci64...
    N5flann17flann_algorithm_tE (equal: 0)
    Unexpected Standard exception from MEX file.
    What() is:Cannot convert 'any' value

That `equal: 0` means that `has_type<flann_algorithm_t>` returns 0, where it returned 1 in all the other cases -- which is what's causing it to throw the exception when I try to `cast<flann_algorithm_t>`. But the `type_info::name()` is the same for all of them.

I see this same behavior on

  * Matlab R2011b and 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

The weird thing is that I could've sworn it worked a few months ago, but maybe I just did a bad job of testing.

Obviously I can get around this by static linking. But why is this happening? Does it have something to do with the way Matlab loads mex files and their libraries? The [last time I had a problem like this](http://stackoverflow.com/q/9011780/344821) it was caused by header conflicts with Matlab's included Boost, but Matlab doesn't include flann.