11

我们正在创建许多使用我们的通信库的 MATLAB MEX 文件。这个通信库大量使用 Boost。现在,MATLAB 在内部也使用了 boost,这意味着在标准设置中,我们不能使用与 MATLAB 附带的不同的 boost 版本,否则一切都会随之而来。

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

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

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

4

1 回答 1

9

一种解决方案是通过编写一个本身不依赖于 boost 的小型加载程序 mex 文件来更改 matlab 打开插件的方式,称之为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。

如果您正确执行 cmdline 链接,使用 'ldd' 您应该会看到 ' foo.mexglx ' 不依赖于 boost,而 ' bar.mexglx ' 具有所有通常的依赖关系。

几个月来我一直在大量使用这种技术,没有明显的失败迹象。我仍然有点担心我不明白的事情可能会出错,但目前这是我唯一的解决方案(除了编写一个完整的进程外执行引擎来复制 mxArray 接口和与管道通信,或静态链接所有内容,这对我的情况不实用)

于 2013-01-02T08:48:25.687 回答