記錄將FLANN演算法編譯成MEX檔案的過程

2021-07-14 13:57:00 字數 1760 閱讀 1581

在重現文章《vocmatch:efficient multiview correspondence for structure from motion》所做的研究工作中,我們遇上了如何將flann演算法的c++**轉換成mex檔案的問題。我們使用的軟體是matlab r2015b以及msvc2010。利用這篇文章,記錄一下debug的過程。

參見:參見:

我們最初遇到的問題為「fatal error c1083: 無法開啟包括檔案:「flann/flann.h」: no such file or directory」

#include

其實這是乙個很低階的問題。在《c++程式設計(第2版)》(吳乃陵 況迎輝著)中對這個問題有如下解釋:「#include方式為標準方式,預處理器將在include子目錄下搜尋由檔名所指明的檔案。這種方式適用於嵌入c++提供的標頭檔案,因為這些標頭檔案一般都存在c++系統目錄的include子目錄下。而對於#include"***",編譯器將首先在當前檔案所在目錄下搜尋,如果找不到,再按標準方式搜尋,這種方式適用於嵌入使用者自己建立的標頭檔案。」 簡單來說,即對於c++本身提供的標頭檔案,用<>;自己編譯的標頭檔案,用""。

用mex的編譯指令編譯數次,改掉幾個同種錯誤之後,我們又遇到非常棘手的乙個錯誤。錯誤如下:

nearest_neighbors.obj : error lnk2019: 無法解析的外部符號 flann_find_nearest_neighbors_int,該符號在函式 "void __cdecl _find_nn(int,struct mxarray_tag * *

const,int,struct mxarray_tag const * * const)" (?_find_nn@@yaxhqeapeaumxarray_tag@@hqeapebu1@@z) 中被引用。

一共有26個同種錯誤。

對於這個問題我們嘗試了很多方案,甚至更換了多個matlab版本,都沒有解決。經我們分析,該錯誤可能是:通過編譯nearest_neighbors.cpp,由於nearest_neighbors.cpp內只包含了flann.h標頭檔案,而flann.h標頭檔案只是函式宣告,函式的實現在flann.hpp和flann.cpp中,但是因為沒有c++工程檔案,所以編譯器在link時找不到函式的實現,故而報錯。我們的解決方案是:將flann.hpp檔案合併進flann.h檔案中,同時刪去flann.hpp檔案;將flann.cpp重新命名為flanncpp.h,在flann.h的末尾新增#include "flanncpp.h"。

完成這一系列改動後,再次使用mex指令編譯nearest_neighbors.cpp,會得到一共error和很多warning,error如下:

error c2228: 「.serialize」的左邊必須有類/結構/聯合

型別是「unsigned __int64」

c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(1271) : fatal error c1128: 節數超過物件檔案格式限制: 請使用 /bigobj 進行編譯。

我們的解決方法是,開啟mex_c++_win64.xml檔案(建議利用mex -v -o指令來找到該檔案的路徑),將其中的compflags="/gr /w3 /ehs /nologo /md $include  $compdefines"修改為          compflags="/gr /w3 /ehs /nologo /md /bigobj $include  $compdefines"

再次編譯,我們成功的得到了mex檔案。

將iconv編譯成lua介面

前一篇博文說了,在cocos2dx中怎麼樣使用iconv轉碼,這節我們將上一節中寫的轉碼函式,做成乙個lua介面,在lua指令碼中使用。luaiconv.h ifndef lua iconv h define lua iconv h include tolua h include tolua eve...

將Js檔案編譯成dll檔案

1.向專案中新增jscript檔案 script 1.js function doclick1 script 2.js function doclick2 2.解決方案資源管理器中,右鍵檢視script 1.js和script 2.js的屬性,把高階中的 生成操作 屬性設定成 嵌入的資源 3.向as...

如何將Sass編譯成CSS

命令編譯 命令編譯就是在終端中輸入sass命令來編譯 sass 這種編譯方式使用起來很簡單。示例 假設現在有乙個sass檔案,檔名為style.scss sass 檔案的副檔名名.scss 我們需要將這個檔案中的 編譯成 css 可以執行如下命令 sass style.scss style.css命...