2016-10-31 27 views
1

私は画像のブレ除去のためのプログラムをコンパイルしようとしています。 は、私は、ファイルapply_blur_kernel_mex.cは、次のコードを持っているmexでCファイルをコンパイルするときにMatlabエラーが発生する

mex apply_blur_kernel_mex.c 

を実行しよう

#include <mex.h> 
#include <stdlib.h> 
#include <math.h> 
#include <matrix.h> 
#include "ow_homography.h" 
... 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
... 
compute_homography_matrix(Ksharp, &theta_list[k*3], invKblurry, H); 
... 
} 

問題が

#ifndef OW_HOMOGRAPHY_H 
#define OW_HOMOGRAPHY_H 

#include "ow_mat3.h" 

INLINE void compute_homography_matrix(const double *Ksharp, const double *theta, const double *invKblurry, double *H) { 
    double R[9]; 
    /* Compute homography */ 
    cp3(invKblurry,H); 
    rot3(theta[0],theta[1],theta[2],R); 
    mmip3(R,H); 
    mmip3(Ksharp,H); 
} 
ow_homography.h別のファイルにある関数compute_homography_matrixであります

この最後の操作(cp3、rot3 ...)は、プログラムのすべての操作を含む別のファイルow_mat3.hにあります。

Error using mex 
Undefined symbols for architecture x86_64: 
    "_compute_homography_matrix", referenced from: 
     mexFunction in apply_blur_kernel_mex.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

任意の提案は、この問題を解決するために: はので、私は次のような問題を持っている

mex apply_blur_kernel_mex.c 

を呼び出すしようとすると? ありがとうございます。

+0

エラーメッセージに記述されている関数の先頭にアンダースコアがありますが、例のコードは – chiliNUT

+0

ではありません。gccにはシンボルにアンダースコアを付けるための素敵な '-fleading-underscore'があります。ダンノについては、clang。 –

答えて

0

http://clang.llvm.org/compatibility.html#inline

C互換C99インライン関数

デフォルトで、クランは、GNU C11モードでCコードを構築し、それは、インラインキーワードの標準 C99セマンティクスを使用します。これらのセマンティクスは、 とGNU C89モードのものとは異なります。これは、5.035より前の GCCバージョンのデフォルトモードです。たとえば、次のコードを考えてみます。

C99で
inline int add(int i, int j) { return i + j; } 

int main() { int i = add(4, 5); return i; } 

は、インライン関数の定義が インライン化のためにのみ提供されることを意味し、プログラム中のどこか(インラインなし)別の定義 があること。つまり、このプログラムは、 が不完全であることを意味します。addがインライン化されていない場合(たとえば、最適化なしで をコンパイルする場合)、メインは他の定義である への未解決の参照を持ちます。そこで我々は、このように(正しい)リンク時のエラー を取得します。これとは対照的に

Undefined symbols: "_add", referenced from: 
     _main in cc-y1jXIr.o 

、(GCCの古いバージョンでは、デフォルトで使用される)GNU C89モード はC89標準プラス機能がたくさんあります。 C89には というインラインキーワードはありませんが、GCCはそれを拡張機能として認識し、ちょうど をオプティマイザのヒントとして扱います。

この問題を解決するには、いくつかの方法があります。

1)の変更は、静的なインライン関数に追加します。これは通常、翻訳ユニットが1つだけ機能を使用する必要がある場合に適切なソリューションです。 静的インライン関数は常に翻訳 ユニット内で解決されるため、プログラム内の別の場所に関数 の非インライン定義を追加する必要はありません。

2)addのこの定義からインラインキーワードを削除します。inlineキーワードは、関数をインライン化するためには必要ではなく、 がそれを保証するものでもありません。一部のコンパイラは完全にそれを無視します。 Clang はそれをプログラマからの軽度の提案として扱います。

3)あなたのプログラムのどこかに外部の(インラインではない)定義を追加してください。 2つの定義は同等でなければなりません!

4)-std = gnu89をClangオプションに追加してGNU C89方言でコンパイルします。このオプションは、プログラムソース を変更できない場合、またはプログラムが追加の C89固有の動作に依存している場合にのみ、変更することはできません。

これはすべてCコードにのみ適用されます。 C++でのインラインの意味は、GNU89またはC99の意味とは全く異なる です。

関連する問題