我在C中编写程序,允许用户实现自定义"功能"由各种口译员经营。我还想让用户在普通的C中编写这些自定义函数,然后动态加载。为了做到这一点,我创建了两个结构,一个用于解释函数,另一个用于本机结构。
这是一个简单的例子:
struct func_lang {
bool is_native;
char* identifier;
// various other properties
}
typedef void (*func_native_ptr)(int);
struct func_native {
bool is_native;
char* identifier;
func_native_ptr func_ptr;
}
然后我使用每个结构的identifier
属性将它们放在一个哈希表中,然后我可以用它来在运行时执行它们。
我的问题实际上来自另一端,加载的库。我希望能够允许加载的库发布"发布"他们想要将哪些功能插入到列表中。例如,可能使用这样的函数:
void register_func_native(char* identifer, func_native_ptr func_ptr);
然后,当我从库中调用init
函数时,他们可以调用此函数将函数插入到哈希表中。
这会有用吗?我对register_func_native
函数如何链接有点困惑,因为加载的库需要它,但必须由加载器本身定义。我的loader函数是否需要在另一个共享库中实现,然后可以在运行时链接?
答案 0 :(得分:2)
它会起作用。共享库可以查看主程序中的所有全局符号。
在主程序中,你需要dlopen()和dlsym()来调用初始化函数。
答案 1 :(得分:2)
这将取决于平台,但在Linux和我见过的所有Unix上,这将起作用。例如:
$ cat dll.c
void print(char const *);
void foo()
{
print("Hello!");
}
$ gcc -Wall -shared -fPIC -o dll.so dll.c
$ cat main.c
#include <dlfcn.h>
#include <stdio.h>
void print(char const *msg)
{
puts(msg);
}
int main()
{
void *lib = dlopen("./dll.so", RTLD_NOW);
void (*foo)() = (void (*)())dlsym(lib, "foo");
foo();
return 0;
}
$ cc -fPIC -rdynamic main.c -ldl
$ ./a.out
Hello!