2013-08-05 54 views
1

我一直試圖實現一個類功能大約一個星期,現在無濟於事。通常情況下,我會滿意的將頭文件中的邏輯,但是,ACML庫與我使用「複雜」包括衝突。長話短說,我需要從一個單獨的cpp文件中調用C ACML庫。下面是我的代碼,我一直無法得到它的工作。我使用Visual Studio 2013的預覽和我正在以下編譯錯誤:將參數傳遞給另一個C++源文件

acml_lapack.h(8): error C3861: 'dgetrf_c': identifier not found 

我如何打電話參數傳遞給物理上位於另一個* .cpp文件的功能?我發現有關該主題的其他帖子,但我必須錯過一些東西,因爲我的代碼無法正常工作。

頭文件:

// acml_lapack.h 
#ifndef __ACML_LAPACK 
#define __ACML_LAPACK 

void dgetrf(int m, int n, double *a, int *ipiv, int &info) 
{ 
    if (m && n) 
    dgetrf_c(&m, &n, a, &m, ipiv, &info); 
} 
#endif 

附加* cpp文件:

// acml_lapack.cpp 
#include <acml.h> 
#include "acml_lapack.h" 

void dgetrf_c(int *m, int *n, double *a, int *lda, int *ipiv, int *info) 
extern "C" { 
    void dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info); //call C AMD Core Math Library lapack 
} 

主源文件:

// source.cpp 
#include <acml_lapack.h> 
using namespace std; 

int main() 
{ 
// **** Start test acml **** 
double A[2][2]; 
A[0][0] = 1; 
A[0][1] = 2; 
A[1][0] = 3; 
A[1][1] = 4; 

cout << "before: " << endl; 
cout << A[0][0] << A[0][1] << endl; 
cout << A[1][0] << A[1][1] << endl; 

int LDA = 2; 
int * output; 

//call external function from another cpp file 
dgetrf(2, 2, *A, &LDA, *output); 

cout << "after: " << endl; 
cout << A[0][0] << A[0][1] << endl; 
cout << A[1][0] << A[1][1] << endl; 

// **** END TEST **** 
} 

回答

0

更改附加cpp文件到

// acml_lapack.cpp 
#include <acml.h> 
#include "acml_lapack.h" 

extern "C" { 
    void dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info); //call C AMD 
} 

void dgetrf_c(int *m, int *n, double *a, int *lda, int *ipiv, int *info) 
{ 
    dgetrf_(m, n, a, lda, ipiv, info); //call C AMD Core Math Library lapack 
} 
0

你錯過函數聲明在頭:

void dgetrf_c(int *m, int *n, double *a, int *lda, int *ipiv, int *info); 

權利之前dgetrf定義。請注意,將函數定義爲(即函數體)放在標題中通常是個不錯的主意,就像您爲dgetrf所做的那樣。原因是你最終會得到幾個散佈在代碼中的相同函數的定義:每個包含定義的頭文件的每個定義包含在其他文件(最可能是cpp文件)中的一個定義,編譯器不知道哪一個定義選擇爲合法的。解決該問題的方法是將dgetrf代碼放入cpp文件中,並且只在頭文件中提供聲明的功能。

+0

是這樣的? void dgetrf(int m,int n,double * a,int * ipiv,int&info) \t { \t \t void dgetrf_c(int * m,int * n,double * a,int * lda,int * ipiv,int *信息); \t \t如果(M && N) \t \t \t dgetrf_c(&M,&N,A&M,IPIV,&info); \t} 我仍然得到這個錯誤: 1> Source.obj:錯誤LNK2005:「已在acml_lapack.obj中定義了「__cdecl dgetrf(int,int,double *,int *,int&)」1> acml_lapack。obj:error LNK2019:無法解析的外部符號dgetrf_在函數中引用「void __cdecl dgetrf_c(int *,int *,double *,int *,int *,int *)」1> C:\ ... \ x64 \ Debug \ Cardinal .exe:fatal error LNK1120:1 unresolved externals – matusi143

+0

確實,如果我將聲明添加到頭文件中,它會拒絕編譯,指出它在多個位置(例如,兩個cpp文件)都被定義。甚至可以將參數從一個源文件傳遞到另一個源文件,而無需編寫接口? – matusi143

+0

你是什麼意思?參數是函數的語法元素,源文件沒有參數。 – didierc

0

函數聲明在頭文件中不可見。如果你需要聲明是可見的,那麼你必須包含你自己的其他頭文件。但是,通常情況下,您不希望函數定義像您一樣在頭文件中存在。原因是,如果你的依賴關係是正確的方式,你將會導致一個函數在一個編譯器單元中被多次定義,而這個編譯器單元將無法構建。

此外,您的主要源文件有#include <acml_lapack.h>而不是#include "acml_lapack.h",這是一個問題。

+0

修正了#include,儘管我仍然沒有看到如何在源文件之間來回傳遞參數,而無需雙聲明該函數。如果不編寫可執行文件之間的接口,我開始認爲這是不可能的。 – matusi143