0

ユーザーがカスタム「関数」を実装して、ある種のインタープリターで実行できるようにするプログラムを C で作成しています。また、ユーザーがこれらのカスタム関数をプレーンな C で記述し、動的にロードできるようにしたいと考えています。これを行うために、インタープリター関数用とネイティブ関数用の 2 つの構造体を作成しました。

簡単な例を次に示します。

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ロードされたライブラリで必要とされるため、関数がどのようにリンクされるかについて少し混乱していますが、ローダー自体で定義する必要があります。ローダー関数を別の共有ライブラリに実装して、実行時にリンクできるようにする必要がありますか?

4

2 に答える 2

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!
于 2013-01-15T23:24:00.907 に答える
2

それが動作します。共有ライブラリは、メイン プログラムにあるすべてのグローバル シンボルを認識します。

メイン プログラムでは、初期化関数を呼び出すために dlopen() と dlsym() が必要です。

于 2013-01-15T22:25:26.507 に答える