実行時にシンボル名からアドレスを取得するために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
注意このメソッドはそのままシンボルテーブルが必要であること。オーバーヘッドを減らすために、上記のコードを初期化ルーチンで再利用することができます。そこには、関数名からアドレスへのマッピングを格納します。これは、ルックアップテーブルを生成するための1回限りのコストをもたらす。
ええ、これは目的全体を敗北させ、さらに、ディスパッチできる20以上の方法を考えていると非常に面倒なコードになります。 – skyel
私が言ったように、あなたがそれについて賢明なら、それを自動的に行うことができます。ディスパッチャはスクリプトによって生成することもできますし、少なくとも、単純なマクロの連続アプリケーションとして書くこともできます。 –
実行時にこのようなことができるかどうかは実際にはわかりません。 2つのファイルのアイデア全体は、以前の時点でfile2.cをコンパイルし、後でそれを変更することなく使用することができました。たとえば、利用可能なメソッドの_char ** _をfile2.cに静的にすることができます。また、いくつかの関数によってidに追加することができます。次に、ディスパッチがあなたの呼び出しの正当性をチェックできます。スクリプト/マクロを使用する場合は、毎回再コンパイルする必要があります。 – skyel