建议"插件"静态库

时间:2016-09-23 09:40:45

标签: c++ static-libraries static-linking

我正在写一首诗的图书馆,但我在设计任务时遇到了困难。我有一个静态库,我想制作一个" 静态插件"系统(原谅名称)。

因此,我想创建一系列符合以下规则的静态库

  • 每个库包含一个单一对象(一个类,或者任何需要的东西)
  • 该类必须包含一个数组
  • 每个数组的项目都是unsigned char
  • 的数组

从本质上讲,我想创建一系列图书馆,在这个任务中提供一系列诗歌。因此,每个图书馆都包含一位作者的诗歌。

现在我需要的部分就是:库用户只需链接所需的静态插件和主库。有了这个,用户可以在控制台上打印整个诗歌库,就像这个简单的例子一样:

#include "poems.hpp"

int main(int argc, const char * argv[])
{
    poems p;

    p.dump(">>> Dumping poems");

    return 0;
}

所有流程均在链接时处理

$ clang++ a.cpp libpoems.a libplugin_coleridge.a 
$ ./a.out
>>> Dumping poems
The Rime of the Ancient Mariner
    It is an ancient Mariner, 
    And he stoppeth one of three. 
[...]
Kubla Khan
    In Xanadu did Kubla Khan 
    A stately pleasure-dome decree: 
[...]

或替代

$ clang++ a.cpp libpoems.a libplugin_shelley.a 
$ ./a.out
>>> Dumping poems
Ozymandias
    O wild West Wind, thou breath of Autumn's being,
    Thou, from whose unseen presence the leaves dead 
[...]
Ode To The West Wind
    O wild West Wind, thou breath of Autumn's being,
    Thou, from whose unseen presence the leaves dead
[...]

我想我可以在poem.hpp中创建包含对外部对象或类似内容的调用的类或类似内容。

欢迎任何提示。

1 个答案:

答案 0 :(得分:0)

我不认为您可以在C / C ++中执行此操作,每个目标文件中只有一个字符串。首先,打印功能需要能够处理某种类型的诗歌列表。

我认为这种事情通常是使用编译器静态对象初始化器(可能通过注册对象)来完成的。

最终,你需要一个主要可以调用的符号,它是一个链接列表。

因此,您可以创建一个类,将我的字符串添加到字符串列表中。类。然后在每个模块中,您执行其中一个加法器的静态实例。

在加载程序时,C ++运行时库将调用静态对象的所有构造函数,因此构造函数应将字符串添加到众所周知的列表中。

未定义构造静态对象的顺序,因此请确保列表是简单的基本类型(指向链表头的指针)或者您是否对列表进行了延迟构造(即第一个构造函数创建列表对象并将其分配给基础指针类型)。

例如:

main.cc

#include <stdio.h>
#include "poem.h"

Poem* s_poemList = NULL;

int main() {
  Poem* poem = s_poemList;

  while (poem) {
    printf("%s\n", poem->text);
    poem = poem->next;
  }
}

poem.h

#ifndef __POEM_H__
#define __POEM_H__

class Poem;

extern Poem* s_poemList;

class Poem {
public:
  Poem(const char* text)
  : text(text) {
    next = s_poemList;
    s_poemList = this;
  }

  class Poem* next;
  const char* text;
};


#endif

poem1.cc

#include "poem.h"
static Poem poem("This is the text from Poem1\n");

poem2.cc

#include "poem.h"
static Poem poem("This is the text from Poem2\n");

如果你这样做,这将创建一个成功的系统:

cc main.cc poem1.cc poem2.cc

每个对象都将链接到可执行文件中,链接器将确保调用构造函数。

但是,如果你将诗歌写成档案:

cc -c poem1.cc
cc -c poem2.cc
ar cr libpoems.a poem1.o poem2.o

然后链接该库:

cc main.cc -lpoems
然后它将无法打印诗歌,因为链接器不需要来自库的目标文件,所以它不会链接它们,所以构造函数不会运行所以列表将保持为空。您需要强制链接器包含库中的对象。在我的Mac上我会这样做:

cc main.cc -Xlinker -force_load ./libpoems.a

其中-Xlinker将以下选项传递给链接器,-force_load告诉链接器包含./libpoems.a文件中的每个对象,即使main.cc不需要它