4

たとえばphpのように外部モジュールでコンパイルできるアプリケーションを実行したいと思います。phpでは、実行時にモジュールをロードすることも、モジュールと一緒にphpをコンパイルすることもできるため、実行時にロードしなくてもモジュールを使用できます。しかし、私はこれがどのように行われるのか理解していません。module.cにモジュールがあり、say_helloという関数が1つある場合、意味を理解していれば、それをメインアプリケーションに登録するにはどうすればよいですか?

/* module.c */
#include <stdio.h>

// here register say_hello function, but how, if i can't in global scope
// call another function?

void say_hello() 
{
  printf("hello!");
}

すべてのファイル(メインアプリ+モジュール)を一緒にコンパイルすると、ユーザーがコードで呼び出した場合にのみ呼び出されるため、メインアプリからsay_hello関数への参照はありません。それで、どうすれば私のアプリに言うことができますか、ねえ、say_hello関数があります、誰かがそれを呼び出したい場合、あなたはそれが存在することを知っています。

編集1:実行時にテーブルのようなものが必要です。ここで、関数と呼ばれるユーザーが存在するかどうかを確認できます(Cと同等です)。ヘッダーファイルは役に立ちません。

EDIT2:私のアプリは私のスクリプト言語を解釈します。

EDIT3:誰かがphpで関数を呼び出す場合、phpinterpretはその関数が存在することを知っている必要があります。ダイナミックリンクについて知っています。.soまたは.dllがロードされると、いくつかの開始ルーチンが呼び出され、そのdllに関数を簡単に登録できるため、phpinterpretateは「say_hello」という関数などのモジュールが登録されているかどうかを確認できます。しかし、たとえばgdサポートを使用してphpをコンパイルしたい場合、gd関数をphp関数リストやハッシュテーブルなどにどのように登録しますか?

4

4 に答える 4

2

あなたが探しているのは動的ライブラリだと思います (一般に、C および OS の世界では、ランタイム ローダブル モジュールを動的/共有ライブラリと呼んでいます)。たとえば、プラグインをサポートして機能を拡張するPidginを取り上げます。これは、プラグインが従わなければならない登録、ロード、アンロード、および使用する機能など、従うプラグインメーカーに特定のインターフェースを提供します。

プログラムが読み込まれると、そのディレクトリでそのような動的ライブラリが検索されplugins、存在する場合は読み込まれて使用され、そうでない場合は機能の公開がスキップされます。インターフェイスが必要な理由は、さまざまなモジュールがさまざまな機能を持つ可能性があるためです。これらの機能は、実行時まで不明です。プラグイン/モジュールと「対話」する共通の合意された方法が必要です。

すべての C プログラムは、静的ライブラリまたは動的ライブラリにリンクできます。static はライブラリから上記のプログラムにコードをコピーし、プログラムを実行するための依存関係を残さないことにより、動的ライブラリにリンクすると、プログラムの起動時に動的ライブラリが存在することが期待されます。3 つ目の方法は、DLL にリンクするのではなく、OS にライブラリのロード操作を実行するように要求することです。これが成功した場合、動的モジュールが使用され、それ以外の場合は無視されます。ロード呼び出しが成功した場合にのみ、動的ライブラリが実行する必要がある機能がユーザーに公開されます。

これはオペレーティング システムが提供する機能であり、使用する言語とは関係がないことに注意してください (ここでは C、C++、または Python は関係ありません)。Cに関する限り、コンパイラは既知のコード、つまりコンパイル時に利用可能なコードにリンクします。これが、オペレーティング システムが異なる理由です。動的モジュールをロードするには、異なるコードを記述する必要があります。さらに、syuch ライブラリのファイル タイプ/形式は、システムごとに異なります。Linux では共有オブジェクト (.so)、Mac ではダイナミック ライブラリ (.dylib)、Windows ではダイナミック リンク ライブラリ (.dll) と呼ばれます。

于 2012-12-26T14:27:40.703 に答える
1

C はインタプリタ言語ではありません。したがって、リンクが必要です。静的リンクまたは動的リンクが必要な場合があります。

プログラムの構築は、コンパイルとリンクという 2 つの主要なフェーズで構成されます。コンパイル中、すべての C ファイルはマシン コードに変換され、呼び出された関数 (objまたはoファイル) は未解決のままになります。次に、リンカーはこれらすべてのファイルを 1 つの実行可能ファイルにマージし、未解決のものを解決します。

これが静的リンクです。リンクされたモジュールは、実行可能ファイルの不可欠な部分になります。

動的リンクはプラットフォーム固有です。ウィンドウの下では、これらは DLL です。システム コールを発行して DLL をロードする必要があります。その後、DLL から関数を呼び出すことができます。

于 2012-12-26T14:20:40.513 に答える
1

必要なのは動的ライブラリです。最初に dlopen(3) の Linux マンページで提供されている例を見てみましょう。

/* Load the math library, and print the cosine of 2.0: */
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen("libm.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror();    /* Clear any existing error */

    /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
       would seem more natural, but the C99 standard leaves
       casting from "void *" to a function pointer undefined.
       The assignment used below is a workaround. */

    *(void **) (&cosine) = dlsym(handle, "cos");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    printf("%f\n", (*cosine)(2.0));
    dlclose(handle);
    exit(EXIT_SUCCESS);
}

C++ dlopen mini HOWTOもあります。

動的読み込みに関する一般的な情報については、まずウィキペディアのページから始めてください。

于 2012-12-26T14:41:14.680 に答える
-5

意味が理解できれば無理だと思います。コンパイル言語だからです。

于 2012-12-26T14:22:21.610 に答える