簡體   English   中英

鏈接MATLAB Mex庫中的錯誤

[英]Linking errors from MATLAB Mex library

我正忙着編寫一個MATLAB Mex庫 - 特別是來自這個網站的'Correlation Clustering Optimization'代碼。

我試圖在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.oQPBO.o 但是,它實際上只在頭文件QPBO.h定義。 因此,我懷疑包含它的兩個源文件都將其作為符號包含在其目標文件中,從而導致鏈接時出現問題。

(進一步的信息:每個源文件還包括一個文件#include "instances.inc"在該文件的最后instances.inc顯然似乎包括模板的一些具體實例QPBO 。)

我在這里犯了一個明顯的錯誤嗎? 我該怎么做才能增加編譯代碼的機會?

編輯

這是GetMaxEdgeNum中有問題的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";
}

似乎問題是某些模板代碼在.cpp文件中。

  1. .cpp文件中刪除#include instances.inc聲明。
  2. 將所有代碼從QPBO.cppQPBO_extra.cppQPBO_maxflow.cppQPBO_postprocessing.cpp移動到頭文件qpbo.h。
  3. 您現在將擁有一個.cpp文件qpbo_wrapper_mex.cpp和一個標頭qpbo.h
  4. mex文件(在matlab中)使用:

     >> mex -O -largeArrayDims qpbo_wrapper_mex.cpp 

應該管用...

GetMaxEdgeNum更改為靜態函數,或將其放入匿名命名空間可能會解決您的問題。

原因是,正如您所建議的那樣,它在兩個目標文件中都有外部鏈接,從而產生名稱標記。 我建議的解決方案給它內部聯系。

編輯后:

如果在類定義中定義方法,它會改變什么嗎? 像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM