3

MATLAB Mexライブラリのコンパイルに問題があります。具体的には、このWebサイトの「CorrelationClusteringOptimization」コードです。

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.

これから判断すると、関数GetMaxEdgeNumはとの両方に表示されていQPBO_extra.oますQPBO.o。ただし、実際にはヘッダーファイルでのみ定義されていますQPBO.h。したがって、それを含む両方のソースファイルがオブジェクトファイルにシンボルとして含まれているため、リンク時に問題が発生していると思われます。

(詳細情報:各ソースファイルには、ファイル#include "instances.inc"最後にファイルも含まれています。instances.incテンプレートの特定のインスタンス化が含まれているようQPBOです。)

私がここで犯している明らかな間違いはありますか?このコードをコンパイルできる可能性を高めるために何ができますか?

編集

GetMaxEdgeNumこれは、次の問題のある関数の定義ですQPBO.h

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

編集2

私のマシンに関する詳細:

  • OSX 10.6.8
  • MATLAB R2012a(R2011bもあります)
  • g++4.2またはg++4.0(またはMacPorts経由のg ++​​ 4.6)

以下の「報奨金の説明」の回答から、私が本当に欲しいものについていくつかの詳細を追加しました。

編集3

instances.inc問題を引き起こしている可能性のあるコンセンサスが少しあります。これは各cppファイルの最後に含まれており、次のものが含まれています。

#include "QPBO.h"

#ifdef _MSC_VER
#pragma warning(disable: 4661)
#endif

// Instantiations

template class QPBO<int>;
template class QPBO<float>;
template class QPBO<double>;

template <> 
    inline void QPBO<int>::get_type_information(char*& type_name, char*& type_format)
{
    type_name = "int";
    type_format = "d";
}

template <> 
    inline void QPBO<float>::get_type_information(char*& type_name, char*& type_format)
{
    type_name = "float";
    type_format = "f";
}

template <> 
    inline void QPBO<double>::get_type_information(char*& type_name, char*& type_format)
{
    type_name = "double";
    type_format = "Lf";
}
4

2 に答える 2

5

問題は、一部のテンプレートコードが.cppファイルに含まれていることのようです。

  1. #include instances.incファイルから宣言を削除し.cppます。
  2. すべてのコードをQPBO.cppQPBO_extra.cppQPBO_maxflow.cpp、およびQPBO_postprocessing.cppからヘッダーファイルqpbo.hに移動します。
  3. これで、単一の.cppファイルqpbo_wrapper_mex.cppと単一のヘッダーqpbo.hが作成されます。
  4. 以下を使用してファイルを(matlabで)mexします。

    >> mex -O -largeArrayDims qpbo_wrapper_mex.cpp
    

動作するはずです...

于 2013-03-11T11:43:00.333 に答える
3

静的関数に変更GetMaxEdgeNumするか、匿名の名前空間に配置すると、おそらく問題が修正されます。

その理由は、ご提案のとおり、両方のオブジェクトファイルに外部リンクがあり、名前が衝突するためです。私の提案する解決策はそれに内部リンクを与えます。

編集後:

クラス定義内でメソッドを定義すると、何かが変わりますか?このような:

template <typename REAL>
class QPB0 {
    ...
public:
    inline int GetMaxEdgeNum() 
    {
        return (int)(arc_max[0]-arcs[0])/2;
    }
    ...
};
于 2013-03-08T16:30:27.380 に答える