【问题标题】:Suggestion for "plugin" static library“插件”静态库的建议
【发布时间】:2016-09-23 09:40:45
【问题描述】:

我正在写诗的图书馆是为了好玩,但我在设计我的任务时遇到了困难。我有一个静态库,我想制作一个“静态插件”系统(请原谅这个名字)。

所以,我想创建一系列遵守以下规则的静态库

  • 每个库都包含一个对象(一个类或任何需要的对象)
  • 类必须包含一个数组
  • 每个数组的项都是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 中创建一些包含对外部对象或类似对象的调用的类或类似内容。

欢迎任何提示。

【问题讨论】:

  • 所以你可以在库中放置一个函数来进行转储,每个库的名称相同,并由链接器解析。那么这里的问题是什么?
  • 不仅仅是一个函数,还包括转储所需的所有数据,或者任何其他函数(例如,搜索一首诗)所需的所有数据。

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


【解决方案1】:

我认为您不能在 C/C++ 中使用每个目标文件中的单个字符串来执行此操作。首先,打印功能需要能够处理某种形式的诗歌列表。

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

最终,您将需要一个 main 可以调用的符号,它是指向您的字符串的链接列表。

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

在加载程序时,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;
  }
}

诗.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 不需要它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2015-04-04
    • 2012-01-05
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多