c - 将数据存储到共享对象中怎么样?

标签 c shared-libraries

例如,我的程序需要加载一些数据。我想快速加载它。

我认为有 3 种加载方式。

  1. 将数据写入JSON或XML并解析数据。
  2. 将数据序列化为某种二进制格式并反序列化。
  3. 将数据写入c文件并编译将数据存入.so,使用dlopen加载共享对象。

第三种方法是个好主意吗? 或者加载持久数据的快速方法是什么?

背景信息:

Where do the data come from?

使用程序的用户创建数据。 可以把数据看成是config,程序是固定的,数据是灵活的。

Does your program only read the data?

不,程序使用它,处理它并可能显示它......

How often will you change the data?

基本上一次,但我认为这并不重要。我只是希望它在程序运行期间每次都能快速加载。

Will you prepare the data on the same machine where your program is running?

不,目标机器非常非常慢...在我使用交叉编译器 (ARM) 的情况下。

更多背景信息:

我有一 block 规范很低的 ARM 板,希望我的程序尽快加载配置数据。所以我想把解析的时间移到数据准备阶段。我不关心便携性或复杂性。只需要速度

最佳答案

Only need speed.

在我当前的项目中,我有一个非常奇怪的build设置。

我目前有大约 100 个具有单个导出结构的 config*.c 文件。我使用 gcc 编译器。图书馆看起来像这样:

// config.h

struct config_s {
    char name[24];
    bool is_debug_enable;
    char some_data[24];
    char some_encryption_key[24];
    /* etc. */
}

const struct config_s *config_get(void);

// config.c  
const struct config_s *config_get(void) {
    extern const struct config_s _config_instatation;
    return &_config_instatation;
}

这 100 多个配置文件的示例如下所示:

// config_kamil.c
#include <config.h>
const struct config_s _config_instatation = {
    .name = "kamil",
    .is_debug_enable = true,
    .some_data = {0x01, 0x02, 0x03, },
    .some_encryption_key = { 0x20, 0x30, 0x40, },
};

链接器在这些 config_*.c 文件中的每一个上被调用 100 多次,并将其与代码库的其余部分链接起来。编译需要花费很长的时间来链接所有这些并且构建配置是一团糟。我得到了 100 多个可执行文件。用户选择他想在哪个设备上放置哪个配置。

或者,我尝试制作一个 __attribute__((__section__("config"))) 并将 _config_instatation 放入该部分。完成 .elf 文件后,我们可以用 objcopy 替换该部分。这很快而且只有一个可执行文件。这导致了错误:编译器足够聪明,可以优化无用代码,它优化了很多,注入(inject)的数据并不总是正确的格式,需要构建一个单独的程序/脚本来编译数据。我选择了更长的编译器,但更简单、更安全的方法。

您声明用户提供配置。根据您的需要(或者更确切地说:如果您的业务计划是向用户收取是否要更改配置的费用),您可以编译一组静态配置并仅向用户提供可执行文件,就像我一样。用户只能看到机器代码。如果他想更改配置,他必须为新的可执行文件付费。

或者你可以设置一个服务,它的工作方式如下:用户将以人类/用户可读的格式发布他的配置,你的服务将把这个配置转换成一个带有解析器和编译器的目标文件,并将它与您的代码库的其余部分,并将可执行文件返回给用户。我可以想象这样的服务可以在用户计算机上下载和安装(带有编译器和所有依赖项等),但我也可以想象这样的服务是基于 http-web-post 的服务。

无论如何,结果数据都嵌入到可执行文件中。因此,它们可以以您希望的最具可读性和可解析性的格式进行解析/准备/准备,以备使用。我不认为你会变得更快。缺点是对于每个配置,您都必须通过编译器,并且对于每个配置,您都会获得一个单独的可执行文件。

关于c - 将数据存储到共享对象中怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57425823/

相关文章:

c - 如何让 gcc 打印出可执行文件所需的共享库的确切路径

c++ - 在共享对象 unix/linux 中查看 c++ 方法/构造函数

c - 为什么static和register存储类不能一起使用呢?

c - 从预填充的随机缓冲区中提取基 K 随机 “bits”

在 c 处创建一个多维数组

android - 在android中使用没有NDK的FFmpeg

DLL 调用约定错误

linker - 链接时:使用-l标志或仅将归档作为输入

困惑 : Pointers and character arrays in C

c - 错误使用字符串化