Проблема загрузки статических библиотек - PullRequest
2 голосов
/ 07 октября 2010

Предположим, я хочу сделать версию библиотеки в бинарных файлах. Для статических библиотек я думал, что этот подход будет работать, но это не так:

LibInfo.h - Базовый класс для всех классов libinfo. Регистрирует объект в gvLibInfo векторе, когда создается ребенок.

#ifndef IFACE_H
#define IFACE_H

#include <vector>

class LibInfo;
extern std::vector<LibInfo*> gvLibInfo;

class LibInfo
{
    public:
        virtual int getversion() = 0;
        void reglib()
        {
            gvLibInfo.push_back(this);
        }

        LibInfo()
        {
            reglib();
        }
        virtual ~LibInfo()
        {}
};


#endif

Lib1.h - Получается из LibInfo и создает объект l1. Lib2.h такой же, только getversion возвращает 2.

#ifndef LIB1_H
#define LIB1_H

#include "LibInfo.h"

class Lib1 : public LibInfo
{
    public:
        int getversion()
        {
            return 1;
        }

    private:
};

Lib1 l1;

#endif

main.cpp

#include "Lib1.h"
#include <iostream>
using namespace std;

vector<LibInfo*> gvLibInfo;

int main()
{       
    for(vector<LibInfo*>::iterator it = gvLibInfo.begin(); it != gvLibInfo.end(); it++)
    {       
        cout << (*it)->getversion() << endl;
    }

    return 0;
}

Компиляция -

g++ -c Lib1.h -o Lib1.o
g++ -c Lib2.h -o Lib2.o
ar cr lib.a Lib1.o Lib2.o
g++ main.cpp -o app -L/home/duminda/statictest/lib.a

Когда я бегу, ничего не происходит. Я подумал, что это может быть из-за одной из нескольких причин:

  1. На момент изготовления Lib1 l1, gvLibInfo не было построено.
  2. Я где-то видел, что компоновщик удалит все неиспользуемые переменные из статической библиотеки. Однако, когда я запускаю двоичный файл nm, он показывает это:

0000000000603280 B gvLibInfo

0000000000603270 B l1

0000000000603278 B l2

Я думаю, l1 & l2 (Соответствующий объект класса Lib2 существует, но что означает этот флаг 'B'? 3. Что-то еще, чего я не знаю.

Ответы [ 2 ]

1 голос
/ 20 декабря 2010

Измените верхнюю часть main.cpp, чтобы она выглядела так, чтобы вектор создавался перед производными экземплярами.

#include "LibInfo.h"

std::vector<LibInfo*> gvLibInfo;

#include "Lib1.h"
#include "Lib2.h"

Кстати, «B» от нм указывает символ в BSS (неинициализированные данные).В справочной странице для nm перечислены все типы символов.

0 голосов
/ 08 октября 2010

В первом ответе на этот вопрос предлагается использовать флаг --whole-archive. Основное отличие состоит в том, что вместо ссылки на внешний объект к внешней функции.

Связывание не происходит с -L, но с -l, то есть должно быть:

-L/path/to/libdir -lname

Если ваша библиотека:

/path/to/libdir/libname.a
...