在MATLAB MEX库中使用boost,与MATLAB的版本不同

Ive*_*ves 11 c++ matlab boost mex

我们正在创建许多使用我们的通信库的MATLAB MEX文件.这个通信库经常使用Boost.现在,MATLAB也在内部使用boost,这意味着在标准设置中,我们不能使用不同于MATLAB附带的升级版本或随之而来的所有地狱.

问题是,我们的参考版本的matlab(boost 1.40)附带的boost版本已经很老了,并且有一些bug.我们非常想使用更新的版本.

我看到的唯一解决方案是创建一个生活在不同命名空间中的自定义版本的boost.然后,名称修改应该防止命名冲突.这个解决方案有点棘手,因为boost还会导出一些"C"符号并且有许多宏都需要更改.

是否有任何推荐的解决方案不需要创建自定义增强版本?

Bri*_*edy 9

一个解决方案是改变matlab打开插件的方式,通过编写一个小的加载器mex文件,它本身不依赖于boost,称之为foo.mexglx

这是mexFunction调用只是这样做

void mexFunction (int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[])
{
  gMexEntry (nlhs, plhs, nrhs, prhs);
}
Run Code Online (Sandbox Code Playgroud)

其中gMexEntry变量是声明为的函数指针

typedef void (*entryfunc_t)(int, mxArray**, int, const mxArray**);
entryfunc_t gMexEntry;
Run Code Online (Sandbox Code Playgroud)

并且在加载模块时由静态构造函数填充(为简洁起见,忽略所有错误检查).

fh = dlopen ('bar.mexglx', RTLD_NOW | RTLD_DEEPBIND );
void * p = dlsym (fh, "mexFunction");
gMexEntry = reinterpret_cast<entryfunc_t> (p);
Run Code Online (Sandbox Code Playgroud)

事件链是当Matlab调用你的函数时,没有boost依赖的瘦包装器将使用dlopen 的RTLD_DEEPBIND选项打开你的函数和boost依赖,这将把符号的查找范围放在这个库中(使用你的版本)提升)在全球范围之前(使用Matlab的旧推动).然后实际的mexFunction调用将转发到bar.

如果你正确地使用'ldd'进行cmdline连接,你应该看到' foo.mexglx '不依赖于boost,' bar.mexglx '拥有你所有常用的依赖关系.

几个月来我一直在使用这种技术,没有明显的失败迹象.我仍然有一些轻微的担忧,我不明白的东西可能会出错,但暂时这是我得到的唯一解决方案(除了编写一个完整的进程外执行引擎复制mxArray接口和与管道通信,或静态链接所有对我的情况不切实际的事情)

  • 假设您正在安装其他mex库以加载与_foo.mexglx_相同的位置,我建议在构建_foo.mexglx_时将`-Wl,-rpath -Wl,$ ORIGIN`添加到链接器标志,这样您就不需要了尝试通过`dlopen`加载库时,使用`LD_LIBRARY_PATH`等进行清理. (2认同)