どのようにロードされたライブラリ関数は、メインアプリケーションで記号を呼ぶだろうか?

StackOverflow https://stackoverflow.com/questions/392416

  •  23-08-2019
  •  | 
  •  

質問

ロードされた共有ライブラリは、関数dlopen()経由で開かれている場合、

、それはメインプログラム内の関数を呼び出すための方法はありますか?

役に立ちましたか?

解決

dlo.c(LIB)のコード:

#include <stdio.h>

// function is defined in main program
void callb(void);

void test(void) {
    printf("here, in lib\n");
    callb();
}

タグを使用してコンパイル
gcc -shared -olibdlo.so dlo.c

ここでは、メインプログラムのコードを(dlopenのマンページからコピーされ、そして調整)

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void callb(void) {
    printf("here, i'm back\n");
}

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

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

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

    *(void **) (&test) = dlsym(handle, "test");

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

    (*test)();
    dlclose(handle);
    exit(EXIT_SUCCESS);
}

タグでのビルド
gcc -ldl -rdynamic main.c

出力:

[js@HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js@HOST2 dlopen]$

-rdynamicオプションが使用されるシンボルの名前だけでなく、(メモリにマップされる)動的シンボルテーブル内のすべてのシンボルを置きます。ここをそれについてさらに読みます。もちろん、あなたはまた、ライブラリとメインプログラム間のインタフェースを定義する関数ポインタ(または関数ポインタの構造体)を提供することができます。それは実際に私はおそらく選ぶだろうどのような方法です。私はそれが窓に-rdynamicを行うことはそう簡単ではないことを他の人から聞いた、それはまた、(あなたが呼び出されないことができるもので、正確なコントロールを持っている)ライブラリとメインプログラム間のクリーナーの通信のためになるだろうが、それはまた、必要となりますより多くのハウスキーピングます。

他のヒント

はい、あなたはあなたのライブラリーにその関数へのポインタを提供する場合、私は、ライブラリは、メインプログラムで関数を実行/実行することができます確信してます。

ここでは一例であり、それはそれほど注意コンパイルされていない。)

/* in main app */

/* define your function */

int do_it( char arg1, char arg2);

int do_it( char arg1, char arg2){
  /* do it! */
  return 1;
}

/* some where else in main app (init maybe?) provide the pointer */
 LIB_set_do_it(&do_it);
/** END MAIN CODE ***/

/* in LIBRARY */

int (*LIB_do_it_ptr)(char, char) = NULL;

void LIB_set_do_it( int (*do_it_ptr)(char, char) ){
    LIB_do_it_ptr = do_it_ptr;
}

int LIB_do_it(){
  char arg1, arg2;

  /* do something to the args 
  ...
  ... */

  return LIB_do_it_ptr( arg1, arg2);
}

dlopen()機能を、@litbにより説明したように、主にELF形式のオブジェクトファイルを使用してシステム上に設けられています。それはかなり強力であり、あなたがロードされたライブラリが参照するシンボルは、メインプログラムから満足することができ、一般的に彼らは満足してみましょうないかどうかを制御できます。すべての共有ライブラリのロードシステムは柔軟性としてありません - それはあなたのコードを移植することになる場合には注意してください。

@hhafezによって概説コールバック機構は、そのコードにキンクがまっすぐにされていることを動作するようになりました。

scroll top