链接MATLAB Mex库中的错误

时间:2013-03-08 16:23:42

标签: c++ macos matlab linker-errors mex

我在编写MATLAB Mex库时遇到了麻烦 - 特别是来自this website的'关联聚类优化'代码。

我正在尝试在OSX机器上编译,并且正在使用提供的mexall函数。这将运行以下行:

mex -O -largeArrayDims CXXFLAGS="\$CXXFLAGS -Wno-write-strings" QPBO.cpp QPBO_extra.cpp QPBO_maxflow.cpp QPBO_wrapper_mex.cpp QPBO_postprocessing.cpp -output QPBO_wrapper_mex

错误发生在链接时与以下输出到MATLAB命令行:

ld: duplicate symbol QPBO<int>::GetMaxEdgeNum()    in QPBO_extra.o and QPBO.o
collect2: ld returned 1 exit status

    mex: link of ' "QPBO_wrapper_mex.mexmaci64"' failed.

从这一点来看,GetMaxEdgeNumQPBO_extra.o中出现了QPBO.o函数。但是,它实际上只在头文件QPBO.h中定义。因此,我怀疑包含它的两个源文件都将其作为符号包含在目标文件中,导致链接时出现问题。

(更多信息:每个源文件还在文件的 end 处包含文件#include "instances.inc"instances.inc显然似乎包含了模板{的某些特定实例。 {1}}。)

我在这里犯了一个明显的错误吗?我该怎么做才能增加编译代码的机会?

修改

这是QPBO中有问题的GetMaxEdgeNum函数的定义:

QPBO.h

编辑2

有关我的机器的更多详细信息:

  • OSX 10.6.8
  • MATLAB R2012a(也有R2011b)
  • g ++ 4.2或g ++ 4.0(或通过MacPorts的g ++ 4.6)

我在下面的“赏金说明”中添加了一些关于我真正想要的答案的细节。

编辑3

template <typename REAL> inline int QPBO<REAL>::GetMaxEdgeNum() { return (int)(arc_max[0]-arcs[0])/2; } 可能导致麻烦的一些共识。这包含在每个instances.inc文件的末尾,它包含以下内容:

cpp

2 个答案:

答案 0 :(得分:5)

似乎问题是某些模板代码在.cpp文件中。

  1. #include instances.inc文件中删除.cpp声明。
  2. 移动 QPBO.cpp QPBO_extra.cpp QPBO_maxflow.cpp QPBO_postprocessing.cpp 中的所有代码到头文件 qpbo.h
  3. 您现在将拥有一个.cpp文件 qpbo_wrapper_mex.cpp 和一个标题 qpbo.h
  4. mex文件(在matlab中)使用:

    >> mex -O -largeArrayDims qpbo_wrapper_mex.cpp
    
  5. 应该工作......

答案 1 :(得分:3)

GetMaxEdgeNum更改为静态函数,或将其置于匿名命名空间中可能会解决您的问题。

原因是,正如您所建议的那样,它在两个目标文件中都有外部链接,从而产生名称标记。我建议的解决方案使其具有内部联系。

编辑后:

如果在类定义中定义方法,它会改变什么吗? 像这样:

template <typename REAL>
class QPB0 {
    ...
public:
    inline int GetMaxEdgeNum() 
    {
        return (int)(arc_max[0]-arcs[0])/2;
    }
    ...
};