一种解决方案是改变 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 依赖项的瘦包装器将使用 boost 依赖项打开您的函数RTLD_DEEPBINDdlopen 选项,这会将这个库中符号的查找范围(使用您的 boost 版本)置于全局范围之前(使用Matlab 的旧boost)。然后实际的 mexFunction 调用将转发到 bar。
如果您正确执行了 cmdline 链接,使用“ldd”您应该看到“foo.mexglx' 不依赖于 boost,并且 '酒吧.mexglx' 拥有您所有常用的依赖项。
我已经大量使用这种技术几个月了,没有明显失败的迹象。我仍然有一些轻微的担心,我不明白的东西可能会出错,但目前这是我唯一的解决方案(除了编写一个完整的进程外执行引擎复制 mxArray 接口和与管道通信,或静态链接所有内容,这对我的情况来说不切实际)