gpt4 book ai didi

c - 静态链接库的类似 dlsym 的行为

转载 作者:太空狗 更新时间:2023-10-29 11:15:45 25 4
gpt4 key购买 nike

我正在尝试在 C 中编写一种调度函数,它应该接收一个由函数名称组成的字符串,然后从调度函数内部调用函数,其名称在接收到的参数中指定。重点是我不想在动态加载的库中定义函数。流程应该是这样的。

文件1.c

void hello()
{
fprintf(stderr,"Hello world\n");
}

void myfunc()
{
mydispatch("hello");
}

文件2.c

void mydispatch(const char *function)
{
...
}

我知道这种结构可能有点奇怪,但我主要想知道是否可以这样做。

最佳答案

您可以使用 BFD 在运行时从符号名称中获取地址。

#include <stdio.h>
#include <stdlib.h>
#include <bfd.h>
#include <string.h>

void func1(int n)
{
printf("%d\n", n);
}

void * addr_from_name(char * filename, char * symname)
{
bfd * ibfd;
asymbol ** symtab;
symbol_info info;
void * symaddress = NULL;
long size;
long syms;
unsigned int i;

bfd_init();

ibfd = bfd_openr(filename, NULL);
bfd_check_format(ibfd, bfd_object);

size = bfd_get_symtab_upper_bound(ibfd);
symtab = malloc(size);
syms = bfd_canonicalize_symtab(ibfd, symtab);

for(i = 0; i < syms; i++) {
if(strcmp(symtab[i]->name, symname) == 0) {
bfd_symbol_info(symtab[i], &info);
symaddress = (void *)info.value;
}
}

bfd_close(ibfd);
return symaddress;
}

int main(void)
{
void (*func)(int) = addr_from_name("/homes/mk08/Desktop/lala", "func1");
printf("%p\n", func);
func(5);
return EXIT_SUCCESS;
}

在这种情况下,我对 filename 进行了硬编码,但动态获取它很简单。假设您的源代码/二进制文件名为 lala,您可以像这样编译和运行:

gcc -Wall -std=gnu99 lala.c -o lala -lbfd && ./lala

在我的系统上,这会打印:

0x400814
5

请注意,此方法需要完整的符号表。为了减少开销,您可以在初始化例程中重复使用上面的代码。在那里,您将存储从函数名称到地址的映射。这导致生成查找表的一次性成本。

关于c - 静态链接库的类似 dlsym 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10279693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com