提问者:小点点

链接器错误:未定义对reference_genome::seqabi:cxx11'的引用


我对c和c++还很陌生,所以请尝试更具体地解释我应该做什么。该程序尝试使用多线程从目录中读取文件,并将信息存储在映射中,以便以后使用。

我一直在寻找类似的职位。但是,我想不通。

在https://github.com/kaldi-asr/kaldi/issues/938中,它说:“如果您获得链接器错误,该错误涉及到std::__cxx11命名空间或标记[abi:cxx11]中的类型的符号的未定义引用,则可能表明您试图将使用_glibcxx_use_cxx11_abi宏的不同值编译的对象文件链接在一起。”

对于未定义的pthread_cancel'(添加“-pthread”标志)引用的解决方案也不起作用。

我的代码是

#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <map>
#include <algorithm>
#include <random>
#include <unistd.h>
#include <cmath>
#include <stdlib.h>
#include <mutex>
#include <sys/wait.h>
#include <filesystem>
#include <string>
#include <pthread.h>

#define time_str(s) (s < 60 ? (to_string(s) + " second(s)") : (s < 3600 ? (to_string((s) / 60) + " minute(s)") : (to_string((s) / 3600) + " hour(s) and " + to_string(((s) % 3600) / 60) + " minute(s)")))
using namespace std;
namespace fs = std::filesystem;

struct MyGenom
{
    vector<string> filepaths;
    map<string, string> seq;
};

void check_rv(int rv) {
    if (rv != 0) {
        printf("Error: Value is %d\n", rv);
        exit(1);
    }
}

struct Reference_Genome {
    static long unsigned int idx;
    static map <string, string> seq;
    static pthread_mutex_t mtxLock;
    static vector <string> filepaths;

    static void writing(string path) {
        ifstream rsf(path);
        string line, cur_chr;
        while (getline(rsf, line)) {
            if (line.substr(0, 1) == ">") {
                cur_chr = line.substr(1);
                seq[cur_chr] = "";
            } else
                seq[cur_chr] += line;
        }
        rsf.close();
    }

    static void *distribution(void *var) {
        string path;
        while (idx < filepaths.size()) {
            check_rv(pthread_mutex_lock(&mtxLock));
            path = filepaths[idx];
            idx++;
            check_rv(pthread_mutex_unlock(&mtxLock));
            writing(path);
        }
        return NULL;
    }

    Reference_Genome(string dir, unsigned int n_threads) {
        cout << "Reading the reference genome from \'" << dir << "\'" << endl;
        for (const auto &entry : fs::directory_iterator(dir))
            filepaths.push_back(entry.path());
        time_t t1 = time(NULL);
        idx = 0;
        // init lock
        int rv = pthread_mutex_init(&mtxLock, NULL);
        check_rv(rv);
        pthread_t workers[n_threads];
        int rs;
        struct MyGenom param;
        for (unsigned int th = 0; th < n_threads; th++) {
            rs = pthread_create(&workers[th], NULL, distribution, (void *)((unsigned long)th));
            check_rv(rs);
        }
        for (unsigned int th = 0; th < n_threads; th++) {
            rs = pthread_join(workers[th], NULL);
            check_rv(rs);
        }
        pthread_mutex_destroy(&mtxLock);

        time_t t2 = time(NULL);
        cout << filepaths.size() << " sequences were read in " << time_str((long) t2 - (long) t1)
             << ".\n----------------\n";
    }
};

int main(int argc, char const *argv[]) {
    string dir = "./data/ex_seq";
    unsigned int n_threads = 5;
    Reference_Genome ref(dir, n_threads);
    cout << "chr6: " << ref.seq["chr6"] << endl;
    cout << "chr9: " << ref.seq["chr9"] << endl;
    cout << "chr13: " << ref.seq["chr13"] << endl;
}

gcc版本是“线程模型:posix gcc版本9.3.0(Ubuntu 9.3.0-10Ubuntu2)”。

错误是

testSeq.cpp:97: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:98: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:99: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::writing(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
/testSeq.cpp:46: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:48: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::distribution(void*)':
testSeq.cpp:55: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:55: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:56: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:57: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:57: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:58: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:58: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:59: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::Reference_Genome(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)':
testSeq.cpp:68: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:70: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:72: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:85: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:88: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
collect2: error: ld returned 1 exit status


共1个答案

匿名用户

在类内部声明静态变量时,还必须在类外部声明一次。在本例中,您可以将其放在C++文件的底部,或者放在函数和定义之间:

long unsigned int Reference_Genome::idx;
map <string, string> Reference_Genome::seq;
pthread_mutex_t Reference_Genome::mtxLock;
vector <string> Reference_Genome::filepaths;

其思想是,您可以将类定义放在头文件中,以便包含在多个不同的编译单元中,但是静态变量只在您选择的一个。cpp文件中定义一次。