你能动态编译和 link/load C 代码成 C 程序吗?
Can you dynamically compile and link/load C code into a C program?
我看了一下eval in C, and it makes sense that if you write a C string parser/evaluator, you can just map it to specific functions in your main C program. But it doesn't actually place it into executable memory from what I understand, like a JIT compiler好像是这样的。我不完全理解 JIT 编译器(我从来没有做过)但我明白了要点。
所以我想知道您是否可以在 C 中创建某种 JIT 编译器,而无需做太多解析 C 字符串和转换为 AST 之类的工作。基本上,您可以像 JavaScript 那样动态创建一个函数(在 C 中),这样该函数与任何其他 C 函数完全相同(即它是 compiled直接进入程序的可执行部分的可执行机器代码。
如果无法做到这一点,第二种方法是动态加载 C imports/files/modules。所以你分拆了一个进程,告诉 clang 编译器编译一些库函数,完成后,在不停止当前程序的情况下,它 links/attaches 新程序库到它自己,因此可以执行代码那样.
如果那不可能,也许一个选择是简单地在后台重新编译程序,然后用从头开始启动的新程序交换当前程序。不过,那将是非常原始的。
试图弄清楚您是否在 C 中有一些用于您自己的自定义函数数据类型的结构,然后如何以最优化的方式在 C 中执行该函数。
在 POSIX 系统(Linix、Mac、UNIX)上,您可以使用 dlopen
和 dlsym
函数。这些函数可用于在 运行 时间加载共享库并从中执行函数。
就创建库而言,最简单的做法是将相关源代码写入文件,运行 gcc 在单独的进程中编译它,然后使用 dlopen
/dlsym
到 运行 它包含的函数。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
const char *libsrc =
"#include <stdio.h>\n"
"\n"
"void f1()\n"
"{\n"
" printf(\"in f1\n\");\n"
"}\n"
"\n"
"int add(int a, int b)\n"
"{\n"
" return a+b;\n"
"}\n";
int main()
{
FILE *libfile = fopen("mylib.c", "w");
fputs(libsrc, libfile);
fclose(libfile);
system("gcc -fPIC -shared -g -Wall -Wextra -o libmylib.so mylib.c");
void *lib = dlopen("libmylib.so", RTLD_NOW);
if (!lib) {
printf("dlopen failed: %s\n", dlerror());
return 1;
}
void (*f)() = dlsym(lib, "f1");
if (f) {
f();
} else {
printf("dlsym for f1 failed: %s\n", dlerror());
}
int (*a)(int, int) = dlsym(lib, "add");
if (a) {
int x = a(2,3);
printf("x=%d\n", x);
} else {
printf("dlsym for add failed: %s\n", dlerror());
}
dlclose(lib);
return 0;
}
还有可以用作库的 Tiny C 编译器,您可以使用它即时编译程序并从现有代码调用新编译代码中的函数 求助于动态库加载。
代码可能不是最优化的 C,但也不算太差。
An example in this answer.
除了 dlload 路径之外,一些表达式计算器和 SIMD 数学内核工具将动态代码生成到内存块中,该内存块可通过 mprotect(2) 和 PROT_EXEC.
尽管这通常不是像 C 那样的 HLL,而只是简单的数学表达式。如果您的要求相当简单,那可能是一条路线。通常它用于简单的功能,这些功能由于它们的使用而对速度敏感,例如。 2D/3D 绘图或图像转换
我看了一下eval in C, and it makes sense that if you write a C string parser/evaluator, you can just map it to specific functions in your main C program. But it doesn't actually place it into executable memory from what I understand, like a JIT compiler好像是这样的。我不完全理解 JIT 编译器(我从来没有做过)但我明白了要点。
所以我想知道您是否可以在 C 中创建某种 JIT 编译器,而无需做太多解析 C 字符串和转换为 AST 之类的工作。基本上,您可以像 JavaScript 那样动态创建一个函数(在 C 中),这样该函数与任何其他 C 函数完全相同(即它是 compiled直接进入程序的可执行部分的可执行机器代码。
如果无法做到这一点,第二种方法是动态加载 C imports/files/modules。所以你分拆了一个进程,告诉 clang 编译器编译一些库函数,完成后,在不停止当前程序的情况下,它 links/attaches 新程序库到它自己,因此可以执行代码那样.
如果那不可能,也许一个选择是简单地在后台重新编译程序,然后用从头开始启动的新程序交换当前程序。不过,那将是非常原始的。
试图弄清楚您是否在 C 中有一些用于您自己的自定义函数数据类型的结构,然后如何以最优化的方式在 C 中执行该函数。
在 POSIX 系统(Linix、Mac、UNIX)上,您可以使用 dlopen
和 dlsym
函数。这些函数可用于在 运行 时间加载共享库并从中执行函数。
就创建库而言,最简单的做法是将相关源代码写入文件,运行 gcc 在单独的进程中编译它,然后使用 dlopen
/dlsym
到 运行 它包含的函数。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
const char *libsrc =
"#include <stdio.h>\n"
"\n"
"void f1()\n"
"{\n"
" printf(\"in f1\n\");\n"
"}\n"
"\n"
"int add(int a, int b)\n"
"{\n"
" return a+b;\n"
"}\n";
int main()
{
FILE *libfile = fopen("mylib.c", "w");
fputs(libsrc, libfile);
fclose(libfile);
system("gcc -fPIC -shared -g -Wall -Wextra -o libmylib.so mylib.c");
void *lib = dlopen("libmylib.so", RTLD_NOW);
if (!lib) {
printf("dlopen failed: %s\n", dlerror());
return 1;
}
void (*f)() = dlsym(lib, "f1");
if (f) {
f();
} else {
printf("dlsym for f1 failed: %s\n", dlerror());
}
int (*a)(int, int) = dlsym(lib, "add");
if (a) {
int x = a(2,3);
printf("x=%d\n", x);
} else {
printf("dlsym for add failed: %s\n", dlerror());
}
dlclose(lib);
return 0;
}
还有可以用作库的 Tiny C 编译器,您可以使用它即时编译程序并从现有代码调用新编译代码中的函数 求助于动态库加载。
代码可能不是最优化的 C,但也不算太差。
An example in this answer.
除了 dlload 路径之外,一些表达式计算器和 SIMD 数学内核工具将动态代码生成到内存块中,该内存块可通过 mprotect(2) 和 PROT_EXEC.
尽管这通常不是像 C 那样的 HLL,而只是简单的数学表达式。如果您的要求相当简单,那可能是一条路线。通常它用于简单的功能,这些功能由于它们的使用而对速度敏感,例如。 2D/3D 绘图或图像转换