这个错误是关于什么的?

What is this error about?

全部,

我正在使用 Anjuta 进行开发。

我为我的主应用程序创建了一个项目,然后又创建了 2 个:1 个用于静态库 (libdbinterface.a) 和 1 个用于动态库 (libsqlite_lib.so)。

这两个库都包含一个导出的 class:libdbinterface.a - class 数据库,libsqlite_lib.so - public SQLiteDatabase : public 数据库.

现在我正在尝试 link libdbinterface.a 到 libsqlite_lib.so。

所以在 Anjuta 中,我为目标 libsqlite_lib.so 添加了以下内容到 "Linker Option":

-L/home/igor/dbhandler/Debug/dbinterface -ldbinterface

但是,在尝试编译时我收到了来自 linker 的以下错误:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/../../../../x86_64-pc-linux-gnu/bin/ld: /home/igor/dbhandler/Debug/dbinterface/libdbinterface.a(database.o): relocation R_X86_64_32S against `_ZTV8Database' can not be used when making a shared object; recompile with -fPIC

我尝试重新编译 libsqlite_lib.so,并明确将 -fPIC 添加到该项目的 "C++ Options",但这并没有解决问题 - 我仍然收到同样的错误。

不幸的是,尝试 Google 如何 link .a 和 .so 没有帮助。

有人可以详细说明如何修复此错误吗?

TIA。

[编辑] libsqlite_lib.so 生成文件 - https://bpaste.net/show/1495231e58cc libdbinterface.a 生成文件 - https://bpaste.net/show/3a71c119d0fc

libdbinterface.a 包含 2 个文件 databse.h:

#ifndef DBMANAGER_DATABASE
#define DBMANAGER_DATABASE

class Field
{
public:
    Field(const std::string &columnName, const std::string &columnType, const std::string &columnDefaultValue = "", const bool columnIsNull = false, const bool columnPK = false)
    {
        column_name = columnName;
        column_type = columnType;
        column_defaultValue = columnDefaultValue;
        column_isNull = columnIsNull;
        column_pk = columnPK;
    }
private:
    std::string column_name, column_type, column_defaultValue;
    bool column_isNull, column_pk;
};

struct FKField
{
    FKField(const std::string &table_name, const std::string &original_field, const std::string &referenced_field)
    {
        tableName = table_name;
        originalField = original_field;
        referencedField = referenced_field;
    }
    std::string tableName, originalField, referencedField;
};

class Table
{
public:
    Table(const std::string &tableName, const std::vector<Field> &tableFields, const std::map<int,std::vector<FKField> > &foreignKeys)
    {
        table_name = tableName;
        table_fields = tableFields;
        foreign_keys = foreignKeys;
    }
    const std::string &GetTableName() { return table_name; }
    std::map<int,std::vector<FKField> > &GetForeignKeyVector() { return foreign_keys; }
private:
    std::string table_name;
    std::vector<Field> table_fields;
    std::map<int,std::vector<FKField> > foreign_keys;
};

#ifdef WIN32
class __declspec(dllexport) Database
#else
class Database
#endif
{
private:
    struct Impl;
    Impl *pimpl;
public:
    Database();
    virtual ~Database();
    Impl &GetTableVector();
    static void *operator new(std::size_t size);
    static void operator delete(void *ptr, std::size_t size);
    virtual int Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg);
    virtual int GetTableListFromDb(std::string &) { return 0; }
};

#endif

和database.cpp:

#ifdef WIN32
#include <windows.h>
#endif
#include <map>
#include <vector>
#include <string>
#include <sqlext.h>
#include "database.h"

struct Database::Impl
{
    std::vector<Table> m_tables;
};

Database::Database() : pimpl( new Impl )
{
}

Database::~Database()
{
    delete pimpl;
}

void *Database::operator new(std::size_t size)
{
    return ::operator new( size );
}

void Database::operator delete(void *ptr, std::size_t size)
{
    return ::operator delete( ptr );
}

Database::Impl &Database::GetTableVector()
{
    return *pimpl;
}

int Database::Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg)
{
    selectedDSN = selectedDSN;
    errorMsg = errorMsg;
    return 0;
}

libsqlite_lib.so 还有 2 个文件:database_sqlite.h

#ifndef DBMANAGER_SQLITE
#define DBMANAGER_SQLITE

#ifdef WIN32
class __declspec(dllexport) SQLiteDatabase : public Database
#else
class SQLiteDatabase : public Database
#endif
{
public:
    SQLiteDatabase();
    ~SQLiteDatabase();
    virtual int Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg);
    virtual int GetTableListFromDb(std::vector<std::wstring> &errorMsg);
protected:
    void GetErrorMessage(int code, std::wstring &errorMsg);
private:
    sqlite3 *m_db;
};

#endif

和 database_sqlite.cpp 与实际实施。 [/编辑]

嗯,显然解决方案是用“-fPIC”重建静态库,而不是动态库。

感谢您的阅读。