challenge メソッド名一覧の表示

リフレクション系のお題の続編です。

「ある与えられたオブジェクトtargetのメソッドのうち、 "test_"で始まるものをすべて呼びだす」というコードを書いてください。 引数に関しては都合のいいように仮定して構いません(全部0個、など)。

メソッドという概念がない言語の場合は、 「複数の関数への参照を持っているようなオブジェクト(たとえばパッケージとかモジュールとか)から"test_"で始まる関数をすべて呼び出す」と読み替えても構いません。

Posted feedbacks - C

C言語にメソッドはないので共有ライブラリの関数を列挙し、呼び出すようにしました。

1. 共有ライブラリをコンパイルします。
% gcc --shared call_tests.c -o tests.so

2. 本体をコンパイルします。
% gcc call_tests.c -o call_tests -ldl -lbfd

3. 実行します
% ./call_tests ./tests.so
hello2
hello1
hello3
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <bfd.h>

void test_hello1()
{
    printf("hello1\n");
}
void test_hello2()
{
    printf("hello2\n");
}
void test_hello3()
{
    printf("hello3\n");
}

int main(int argc, char *argv[]){
    void *handle;
    void (*func)();
    bfd *abfd;
    asymbol *store;
    int symcount;
    void *minisyms;
    size_t size;
    int i;
    bfd_byte *from, *fromend;
    asymbol *sym;
    const char *name;

    if(argc < 2) return EXIT_FAILURE;
    handle = dlopen(argv[1], RTLD_LAZY);
    if(!handle) return EXIT_FAILURE;
    abfd = bfd_openr(argv[1], NULL);
    if(!abfd) return EXIT_FAILURE;
    bfd_check_format(abfd, bfd_object);
    store = bfd_make_empty_symbol(abfd);
    symcount = bfd_read_minisymbols(abfd, 0, &minisyms, &size);
    from = (bfd_byte *)minisyms;
    fromend = from + symcount * size;
    for (; from < fromend; from += size){
        sym = bfd_minisymbol_to_symbol(abfd, 0, from, store);
        if(sym->flags != (BSF_FUNCTION | BSF_GLOBAL)) continue;
        name = bfd_asymbol_name(sym);
        if(strncmp(name, "test_", 5)) continue;
        func = dlsym(handle, name);
        func();
    }
    
    bfd_close(abfd);
    dlclose(handle);
    return EXIT_SUCCESS;
}

Index

Feed

Other

Link

Pathtraq

loading...