C++ 在MATLAB MEX库中使用boost,不同于MATLAB';s版本

C++ 在MATLAB MEX库中使用boost,不同于MATLAB';s版本,c++,matlab,boost,mex,C++,Matlab,Boost,Mex,我们正在创建大量使用我们的通信库的MATLAB MEX文件。这个通信库大量使用Boost。现在,MATLAB在内部也使用boost,这意味着在标准设置中,我们不能使用与MATLAB附带的版本不同的boost版本,否则一切都会发生 问题是,我们的matlab参考版本(Boost1.40)附带的boost版本非常旧,并且有一些bug。我们非常希望使用更新的版本 我看到的唯一解决方案是创建一个位于不同名称空间中的boost自定义版本。然后,名称损坏应该可以防止命名冲突。这个解决方案有点棘手,因为boo

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

问题是,我们的matlab参考版本(Boost1.40)附带的boost版本非常旧,并且有一些bug。我们非常希望使用更新的版本

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


有没有不需要创建自定义boost版本的推荐解决方案?

一种解决方案是通过编写一个本身不依赖于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=重新解释铸型(p);
事件链是,当Matlab调用您的函数时,没有boost依赖项的瘦包装器将使用dlopen的RTLD_DEEPBIND选项打开具有boost依赖项的函数,该选项将此库中符号的查找范围(使用您的boost版本)置于全局范围之前(使用Matlab的旧boost)。然后实际的mexFunction调用将转发到bar

如果您正确地执行cmdline链接,使用“ldd”,您应该会看到“foo.mexglx”对boost没有依赖关系,“bar.mexglx”具有所有常见的依赖关系


我已经大量使用这项技术好几个月了,没有明显的失败迹象。我仍然有一些轻微的担心,我不理解的事情可能会出错,但目前这是我唯一的解决办法(除了编写一个完整的进程外执行引擎,复制mxArray接口并与管道通信,或者静态链接所有不适合我的情况的内容)

您是否尝试过使用
-l
选项指定Boost库的完整路径?为什么会这样?我明天会试试,只是好奇。也许这样它可以链接到您的Boost库,而不是MATLAB的。我们刚刚尝试过,没有成功。libboost_thread.so.1.40仍在使用,所以它仍然崩溃。假设您正在安装如果要在与foo.mexglx相同的位置加载其他mex库,我建议在构建foo.mexglx时,将
-Wl,-rpath-Wl,$ORIGIN
添加到链接器标志中,以便在尝试通过
dlopen
加载库时,不需要使用
LD\u LIBRARY\u PATH
等。
fh = dlopen ('bar.mexglx', RTLD_NOW | RTLD_DEEPBIND );
void * p = dlsym (fh, "mexFunction");
gMexEntry = reinterpret_cast<entryfunc_t> (p);