2016-11-01 56 views
0

我能夠從命名空間引用函數,但不能引用類。這裏是空間文件SeqLib/FermiAssembler.h」能夠引用函數,但不在命名空間中的類

#ifndef SEQLIB_FERMI_H 
#define SEQLIB_FERMI_H 

#include <string> 
#include <cstdlib> 
#include <iostream> 

namespace SeqLib 
{ 

    void print_my_name(){ std::cout << "It's Crt" } 
    class FermiAssembler { 
    public: 
     FermiAssembler(); 

     ~FermiAssembler(); 

     void AddReads(const BamRecordVector& brv); 
    }; 
} 

我能夠調用print_my_name() via SeqLib::print_my_name()但是,無法通過SeqLib::FermiAssembler f

這裏是我的/src

內的C++文件,以引用FermiAssembler類
#include <iostream> 
#include <Rcpp.h> 
#include "SeqLib/FermiAssembler.h" 
using namespace std; 

// [[Rcpp::export]] 
void whats_my_name(){ 
    SeqLib::FermiAssembler f; 

這裏是封裝件的結構

temp 
    seqLib 
    SeqLib 
    src 
     FermiAssembler.cpp 
    SeqLib 
     FermiAssembler.h 
    headerFiles 
    SeqLibCommon.h 
    src 
    hello_world.cpp 
    Makevars which contains PKG_CXXFLAGS= -I../SeqLib 

這裏是FermiAssembler.cpp定義

#include "SeqLib/FermiAssembler.h" 
#define MAG_MIN_NSR_COEF .1 

namespace SeqLib { 
    FermiAssembler::~FermiAssembler() { 
     ClearReads(); 
     ClearContigs(); 
    } 
} 

的錯誤信息是:Error in dyn.load(dllfile) :
unable to load shared object 'temp/seqLib/src/SeqLib.so':
temp/seqLib/src/SeqLib.so: undefined symbol: _ZN6SeqLib14FermiAssemblerD1Ev

更新我已經移動了整個子模塊到src文件夾爲例如:

# temp 
# |─── src 
#  |────SeqLib 
#    |──────SeqLib 
#      |────── FermiAssembler.h 
#    |──────src 
#      |────── FermiAssembler.cpp 

回答

3

當您看到引用類似的錯誤,第一步是通過一個名字demangler像c++filt,其中應包括在任何Linux發行版來運行它:

$ c++filt _ZN6SeqLib14FermiAssemblerD1Ev 
# SeqLib::FermiAssembler::~FermiAssembler() 

的問題是,在你的頭文件,你有宣佈該類的析構函數FermiAssembler,但沒有爲其提供定義。你的選擇是

  1. 完全刪除聲明。如果這個類的析構函數沒有做任何特殊的事情,比如釋放動態分配的內存,或者記錄信息等,那麼編譯器生成的默認析構函數應該沒問題。然而,如果你提供了一個如上所述的聲明,那麼你正在告訴編譯器「這個類的析構函數需要做額外的事情,所以不要爲我生成一個」
  2. 提供一個空定義~FermiAssembler() {}(注意牙套,其中區分該從聲明)。這相當於使用編譯器生成的析構函數,如上所述。
  3. 提供非空定義在這個簡單的例子中,FermiAssembler類不需要非默認析構函數,但爲了演示目的,我們將在下面探討這個選項。

這是我將要使用的文件格式;你需要調整你的路徑,等等。相應地:

tree example/ 

# example/ 
# ├── DESCRIPTION 
# ├── example.Rproj 
# ├── NAMESPACE 
# ├── R 
# │   └── RcppExports.R 
# └── src 
#  ├── demo.cpp 
#  ├── FermiAssembler.cpp 
#  ├── FermiAssembler.h 
#  └── RcppExports.cpp 

FermiAssembler.h現在變爲:

#ifndef SEQLIB_FERMI_H 
#define SEQLIB_FERMI_H 

namespace SeqLib { 

class BamRecordVector; 

void print_my_name(); 

class FermiAssembler { 
public: 
    FermiAssembler(); 

    ~FermiAssembler(); 

    void AddReads(const BamRecordVector& brv); 
}; 

} // SeqLib 

#endif // SEQLIB_FERMI_H 

注意,我也轉換print_my_name到一個函數原型,所以它也將需要相應的源文件中所定義的。此外,您還可以將以前#include s到源文件,因爲他們不再需要在這裏:

// FermiAssembler.cpp 
#include "FermiAssembler.h" 
#include <iostream> 
#include <Rcpp.h> 

namespace SeqLib { 

void print_my_name() { 
    std::cout << "It's Crt"; 
} 

FermiAssembler::FermiAssembler() 
{ 
    Rcpp::Rcout << "FermiAssembler constructor\n"; 
} 

FermiAssembler::~FermiAssembler() 
{ 
    Rcpp::Rcout << "FermiAssembler destructor\n"; 
} 

} // SeqLib 

最後,文件,使這個類的使用:

// demo.cpp 
#include "FermiAssembler.h" 

// [[Rcpp::export]] 
int whats_my_name() { 
    SeqLib::FermiAssembler f; 

    return 0; 
} 

建立和安裝包裝後,它按預期工作:

library(example) 
whats_my_name() 
# FermiAssembler constructor 
# FermiAssembler destructor 
# [1] 0 

更新關於你的問題「能有源文件比頂級src/目錄其他地方嗎?」,是的,你可以,但我通常會建議不要這樣做,因爲它需要一個不平凡的Makevars文件。現在,使用此佈局,

tree example 

# example 
# ├── DESCRIPTION 
# ├── example.Rproj 
# ├── man 
# ├── NAMESPACE 
# ├── R 
# │   └── RcppExports.R 
# ├── SeqLib 
# │   ├── SeqLib 
# │   │   └── FermiAssembler.h 
# │   └── src 
# │    └── FermiAssembler.cpp 
# └── src 
#  ├── demo.cpp 
#  ├── Makevars 
#  └── RcppExports.cpp 

我們在頂級src/目錄(SeqLib/src)這個Makevars

PKG_CXXFLAGS= -I../SeqLib 

SOURCES = $(wildcard ../SeqLib/*/*.cpp *.cpp) 
OBJECTS = $(wildcard ../SeqLib/*/*.o *.o) $(SOURCES:.cpp=.o) 

注意,在上面的例子中,我們簡單地編譯所有目標文件到相同的共享庫。例如,如果您需要編譯中間共享庫或靜態庫並將它們鏈接到最終的.so,那麼預計您的Makevars會變得更加混亂。


改造和安裝,

library(example) 
whats_my_name() 
# FermiAssembler constructor 
# FermiAssembler destructor 
# [1] 0 

+0

感謝深入的答案!我實際上已經在一個單獨的文件中定義了析構函數,請參閱編輯的答案。 – Crt

+0

我不明白你的意見。 – nrussell

+0

我編輯了原始問題以包含析構函數的**定義**。 – Crt

相關問題