2016-05-10 2 views
2

シナリオ:選択シンボルのみの動的?

実行可能ファイルは、実行時にdlopenによって共有オブジェクトをロードします。

共有オブジェクトは、実際にメインの実行可能ファイルにコンパイルされたシンボル(関数)を参照します。

実行可能ファイルをリンクするときに-rdynamicをgccに追加すると正常に動作します。

-rdynamicは、実行ファイルの非静的シンボルをすべてエクスポートします。私の共有オブジェクトには選択された少数しか必要ありません。

質問:-rdynamicの効果を実現する方法はありますか、私の共有オブジェクトで必要とされる少数の選択シンボルを制限していますか?

編集:

、少なくとも2人が質問を誤解し、私は明らかにしてみてください。

この質問は、メインの実行ファイルからシンボルをエクスポートについてです。

この質問は、ダイナミックライブラリからシンボルをエクスポートすることに関するについては、ではありません。ここ

は最小限の例である:

func.h、共通ヘッダファイル

#include <stdio.h> 
void func(void); 

main.cの、メイン実行可能なコード:

#include <dlfcn.h> 
#include "func.h" 

// this function is later called by plugin 
void func(void) { 
    printf("func\n"); 
} 

int main() { 
    void * plugin_lib = dlopen("./plugin.so", RTLD_NOW); 
    printf("dlopen -> %p, error: %s\n", plugin_lib, dlerror()); 

    // find and call function "plugin" in plugin.so 
    void (*p)(void); // declares p as pointer to function 
    p = dlsym(plugin_lib, "plugin"); 
    p(); 

    return 0; 
} 

plugin.c、コード実行時にロードされるプラグインの場合:

#include "func.h" 

void plugin() 
{ 
    printf("plugin\n"); 
    func(); 
} 

私はその後

$ gcc -o main main.c -ldl 
$ gcc -shared -fPIC -o plugin.so plugin.c 

でコンパイルplugin.soそれは解決できないシンボルfuncを、参照するため、ロードできない場合は、次の

$ ./main 
dlopen -> (nil), error: ./plugin.so: undefined symbol: func 
Segmentation fault (core dumped) 

私はそのすべてエクスポートする主な実行ファイルを説得することができます

$ gcc -rdynamic -o main main.c -ldl 
$ ./main 
dlopen -> 0x75e030, error: (null) 
plugin 
func 

しかし、これは不必要にすべてのシンボルでいっぱいになります。

(この動的シンボルテーブルがnm -D mainで検査することができます。)

質問は、私が唯一の主要な実行ファイルのダイナミックシンボルテーブルに「FUNC」、そしてないすべてのものを追加する方法、です。

+0

[Linuxでの共有ライブラリ関数の明示的なエクスポート]の可能な複製(http://stackoverflow.com/questions/2164827/explicitly-exporting-shared-library-functions-in-linux) – greydet

+0

[How to call私のライブラリから実行可能ファイル内の関数?](http://stackoverflow.com/questions/6292473/how-to-call-function-in-executable-from-my-library) – ninjalj

+0

@ninjaljニースfind!その質問自体は私の質問ではありません。しかし、それはまた、私の質問をanwers答えはhttp://stackoverflow.com/posts/6298434/revisionsを持っています。 –

答えて

0

GCCのvisibility属性を使用して実行できます。

エクスポートする関数を__attribute__ ((visibility ("default")))フラグで宣言します。次に、ライブラリ全体をコンパイルして、-fvisibility=hidden引数をGCCに渡します。

詳細については、GCC documentation pageを参照してください。

+0

ありがとうございます。しかし、いいえ。私の質問は、ライブラリからではなく、メインの実行可能ファイルからシンボルをエクスポートすることです。 –

1

残念ながら、これを実行可能ファイルで実現するのは難しいです。エクスポートするシンボルのリストを生成してから、-Wl,--dynamic-list=symfile.txtLDFLAGSに追加する必要があります。

Here's exampleこれはClang(そしてシンボルファイルを生成するために使用するスクリプトhereのもの)の仕組みです。

+0

はい、-Wl、 - dynamic-list = <記号のリストを含むテキストファイル>はそれを行う方法です。シンボルファイルの例については、https://stackoverflow.com/posts/6298434/revisionsを参照してください。 –