这是如何在Linux上完全使用内存(而不写入/tmp/xxx)并使用带有memfd_create的内存文件描述符进行操作的方法:
user@system $ ./main < example-library.so
add(1, 2) = 3
int add(int a, int b) { return a + b; }
#include <cstdio>
#include <dlfcn.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <vector>
int main() {
std::vector<char> library_contents;
char buffer[1024];
ssize_t bytes_read;
while ((bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0) {
library_contents.insert(library_contents.end(), buffer,
buffer + bytes_read);
}
int fd = memfd_create("shared_library", 0);
if (fd == -1) {
perror("memfd_create failed");
return 1;
}
if (write(fd, library_contents.data(), library_contents.size()) !=
static_cast<ssize_t>(library_contents.size())) {
perror("write failed");
return 1;
}
char path[100];
snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
void *handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
fprintf(stderr, "dlopen failed: %s\n", dlerror());
return 1;
}
int (*add)(int, int) =
reinterpret_cast<int (*)(int, int)>(dlsym(handle, "add"));
if (add == NULL) {
fprintf(stderr, "dlsym failed: %s\n", dlerror());
return 1;
}
printf("add(1, 2) = %d\n", add(1, 2));
dlclose(handle);
close(fd);
return 0;
}
/run/shm
时,文件永远不会被写入磁盘。 - yugr/run/shm
不是 POSIX,它是 Linux 特有的。如果没有它,该函数将退回到仅写入/tmp
。无论文件是否成功写入磁盘(在某些系统上,/tmp
可能是一个 ramdisk),您仍然必须与文件系统交互,具备创建它的权限,控制其他人是否可以访问它,在完成时确保正确取消链接它(或崩溃)。为什么不发布一个答案,让人们评论和投票呢? - Parakleta/tmp
回退之外,这些解决方案之间没有任何交集。这两个解决方案在各自的平台上都有优点,但我不明白它们之间的关系。基本上,在BSD上使用fdlopen
而无需访问文件系统,然后在Linux上使用/run/shm
或在POSIX上使用/tmp
,都需要访问文件系统。 - Parakleta