这个错误是什么?

时间:2016-03-19 23:54:55

标签: dynamic-linking static-linking

ALL,

我使用Anjuta进行开发。

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

这两个库每个都包含一个导出的类:libdbinterface.a - 类Database,libsqlite_lib.so - public SQLiteDatabase:public Database。

现在我试图将libdbinterface.a链接到libsqlite_lib.so。

所以在Anjuta中我添加了以下链接选项"对于目标libsqlite_lib.so:

  

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

但是,尝试编译我从链接器收到以下错误:

/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 ++选项"那个项目,但没有解决它 - 我仍然收到同样的错误。

不幸的是,尝试谷歌如何链接.a和.so是没有用的。

有人可以解释如何修复此错误吗?

TIA。

[编辑] libsqlite_lib.so Makefile - https://bpaste.net/show/1495231e58cc libdbinterface.a Makefile - 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一起实际实现。 [/编辑]

1 个答案:

答案 0 :(得分:0)

嗯,显然解决方案是使用&#34; -fPIC&#34;重建静态库,而不是动态库。

感谢您的阅读。