我们正在创建许多使用我们的通信库的MATLAB MEX文件。这个通信库经常使用Boost。现在,MATLAB也在内部使用boost,这意味着在标准设置中,我们不能使用不同于MATLAB附带的升级版本或随后的所有地狱。
问题是,我们的matlab参考版本(boost 1.40)附带的boost版本已经很老了,并且有一些bug。我们非常想使用更新的版本。
我看到的唯一解决方案是创建一个位于不同命名空间的自定义版本的boost。然后,名称修改应该防止命名冲突。这个解决方案有点棘手,因为boost还会导出一些“C”符号并且有许多宏都需要更改。
是否有任何推荐的解决方案不需要创建自定义增强版本?
答案 0 :(得分:9)
一个解决方案是改变matlab打开插件的方式,通过编写一个小的加载器mex文件,它本身不依赖于boost,称之为 foo.mexglx
这是mexFunction调用只是这个
void mexFunction (int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[])
{
gMexEntry (nlhs, plhs, nrhs, prhs);
}
其中gMexEntry变量是声明为
的函数指针typedef void (*entryfunc_t)(int, mxArray**, int, const mxArray**);
entryfunc_t gMexEntry;
并在加载模块时由静态构造函数填充(为简洁起见,忽略所有错误检查)。
fh = dlopen ('bar.mexglx', RTLD_NOW | RTLD_DEEPBIND );
void * p = dlsym (fh, "mexFunction");
gMexEntry = reinterpret_cast<entryfunc_t> (p);
事件链是当Matlab调用你的函数时,没有boost依赖的瘦包装器将使用dlopen的 RTLD_DEEPBIND 选项打开你的函数,它将放置你的函数,将放置这个库中符号的查找范围(使用你的boost版本)在全局范围之前(使用Matlab的旧版本)。然后实际的mexFunction调用将转发到bar。
如果你正确地使用'ldd'进行cmdline链接,你应该看到' foo.mexglx '不依赖于boost,' bar.mexglx '拥有所有常见的依赖关系。
我几个月来一直在使用这种技术,没有明显的失败迹象。我仍然有一些轻微的担忧,我不明白的东西可能会出错,但暂时这是我得到的唯一解决方案(除了编写一个完整的进程外执行引擎复制mxArray接口和与管道沟通,或静态链接所有对我的情况不切实际的东西)