c - 如何将.h文件的内容插入字符串以进行运行时编译?



我正在研究一个C程序的一部分,其中用户输入网络过滤器字符串(想想Wireshark)。 筛选器字符串,例如

(s->field_a == 1 || s->field_c <= 10) && ! (s->field_c % 2)

由用户输入并粘贴到临时文件中的函数中,该文件被编译为共享库并加载 wit dlopen。该函数仅计算字符串。

现在,"s"结构的类型在某个.h文件中定义,比如struct.h。 显然,struct.h 将不可用于运行时编译。我可以将其内容粘贴到字符串中并fprintf它,但是每当我更改标题时,我都必须重新粘贴它。

我可以编写一个在构建过程中执行此操作的脚本,但也许有更好的选择。

有没有办法使用例如预处理器将文件的内容"粘贴"为字符串?

一些代码来说明我正在尝试做什么:

结构体.h:

struct example_struct
{
int field_a;
int field_b;
int field_c;
};

主.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "struct.h"
int main(int argc, char *argv[]) {
struct example_struct s;
char filter_string[] = "(s->field_a == 1 || s->field_c <= 10) && ! (s->field_c % 2)"; // what the user can input
FILE *f = fopen("/tmp/prog.c","w");
// here I'd like to insert contents of struct.h into f
fprintf(f, "int filter(struct example_struct * s) {n");
fprintf(f, "return (%s);}n", filter_string);
fclose(f);
system("gcc /tmp/prog.c -o /tmp/prog.so -shared -fPIC");
// load and use function...
}

编辑: 我不需要实际表示为 char[],它可以是字符串文字。

在构建程序之前,我尽量不使用xxd或其他工具,我可以通过使用 python 脚本或其他任何东西插入文本来做到这一点。我只是好奇"纯粹"的解决方案是否可行。

有没有办法使用例如预处理器将文件的内容"粘贴"为字符串?

[...]

在构建程序之前,我尽量不使用 xxd 或其他工具,我可以通过使用 python 脚本或其他任何东西插入文本来做到这一点。我只是好奇"纯粹"的解决方案是否可行。

C 语言没有用于将编译时文件内容作为字符数组内容包含的内置功能,无论是字符串文本形式还是任何其他类型的初始值设定项形式。 如果你想要它,那么你需要使用某种代码生成器。

但我想暂时挑战你的假设。 你说,

显然,struct.h 将不可用于运行时编译。

,但我不明白为什么这必须是真的。 至少在原则上,没有什么可以阻止您将头文件与程序打包在一起,将其安装在程序已知的位置(或程序可以发现或配置的位置)并将其用作普通头文件。

找到了一个带有定义的技巧,可以在这里做到这一点。 这有点古怪,但它完全符合我的需求。

在结构体中:

#ifndef STRINGIFY
#define STRINGIFY(x) x
#endif
STRINGIFY (
struct example_struct
{
int field_a;
int field_b;
int field_c;
}; )
#undef STRINGIFY

这样,当它作为常规文件包含在内时,定义不会执行任何操作。 在main.c中,我现在可以按如下方式插入字符串:

#define STRINGIFY(x) #x
const char * header_string = 
#include "struct.h"
;
#undef STRINGIFY

来自"struct.h"的代码将作为字符串文字包含在内。

这不是一个语言问题,但一些开发系统可能会有所帮助。例如,Windows API具有资源的概念,它允许在可执行文件中嵌入文件,并在运行时或多或少地访问该资源,就好像它是内部文件一样。

根据其他SO问题:

  • 使用 GCC 在可执行文件中嵌入资源
  • 带有 GCC 的 C/C++:静态将资源文件添加到可执行文件/库
  • 是否有Linux等效于Windows的"资源文件"?

(可能还有其他:只需遵循可能的重复链接),Linux 上的 gcc 有多种方法,从直接使用ld链接器到使用 ImageMagick 等外部工具。

但恕我直言,仅将 .h include 文件包含在使用该应用程序所需的可分发文件包中并没有错。

最新更新