Static lib loading related issue

你离开我真会死。 提交于 2019-12-12 20:15:57

问题


Suppose I want to version the libs in binaries made. For static libs, I thought this approach would work but it does not:

LibInfo.h - Base class for all libinfo classes. Registers an object in gvLibInfo vector when a child is constructed.

#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 - Derived from LibInfo and creates an object l1. Lib2.h is the same except getversion returns 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;
}

Compiling -

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

When I run, nothing happens. I thought this maybe due to one of several reasons:

  1. At the time Lib1 l1 is made, gvLibInfo has not been constructed.
  2. I saw somewhere that the linker will remove any unused variables from a static lib. However, when I run on the binary nm it shows up this :

0000000000603280 B gvLibInfo

0000000000603270 B l1

0000000000603278 B l2

I guess l1 & l2(The corresponding object of class Lib2 are there but what does that 'B' flag mean? 3. Something else I don't know.


回答1:


The first answer to this question propose to use the --whole-archive flag. The main difference is, instead of referring to an external object, the library refers to an external function.

Linking does not occur with -L, but with -l, i.e. it should be :

-L/path/to/libdir -lname

If your library is :

/path/to/libdir/libname.a



回答2:


Change the top of main.cpp to look like this, so that the vector is created before the derived instances.

#include "LibInfo.h"

std::vector<LibInfo*> gvLibInfo;

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

BTW, the 'B' from nm indicates symbol in BSS (uninitialized data). The man page for nm has all the symbol types listed.



来源:https://stackoverflow.com/questions/3880380/static-lib-loading-related-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!