我正在研究一个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 文件包含在使用该应用程序所需的可分发文件包中并没有错。