【问题标题】:Using boost in MATLAB MEX library, different from MATLAB's version在 MATLAB MEX 库中使用 boost,与 MATLAB 的版本不同
【发布时间】:2012-12-05 17:25:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您是否尝试使用 -l 选项指定 Boost 库的完整路径?
  • 这有什么关系?无论如何我明天会试试,只是好奇。
  • 也许这样它可以链接到你的 Boost 库而不是 MATLAB 的。
  • 我们刚刚试了一下,没有成功。 libboost_thread.so.1.40 仍在使用,所以它仍然崩溃。

标签: c++ matlab boost mex


【解决方案1】:

一个解决方案是改变 matlab 打开插件的方式,通过编写一个本身不依赖于 boost 的小型加载程序 mex 文件,将其命名为 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 依赖的函数,这将放置此库中符号的查找范围(使用您的 boost 版本)在全局范围之前(使用 Matlab 的旧 boost)。然后实际的 mexFunction 调用将转发到 bar。

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

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

【讨论】:

  • 假设您正在安装其他 mex 库以加载到与 foo.mexglx 相同的位置,我建议在构建 时将 -Wl,-rpath -Wl,$ORIGIN 添加到链接器标志foo.mexglx 这样您在尝试通过dlopen 加载库时就不需要使用LD_LIBRARY_PATH 等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多