2

Linux で dlopen と dlsym を使用して、次の 2 つのソース ファイルを機能させます。

 #include <dlfcn.h>
 #include <stdio.h>
 int main()
 {
     int *(func)(void);

     func=dlsym( dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

     printf("%d\n", *func());
     return 0;
}

と:

int func()
{
return 42;
}

しかし、最初のものをコンパイルすると、次のように言い続けます:

main.c:9: エラー: 代入の左オペランドとして左辺値が必要です

編集: キャストを追加して、それを関数ポインターにしようとしましたが、今では次のように表示されます: main.c:(.text+0x1f): dlopen' main.c:(.text+0x2b): undefined reference todlsym への未定義の参照'

4

3 に答える 3

4

あなたの宣言funcは混乱しています:

int *(func)(void);

次と同等です。

int *func(void);

funcしたがって、変数を宣言せずにコンパイラにプロトタイプを与えるだけです。関数が有効な左辺値ではないため、エラーが発生します。ただし、関数へのポインターは有効な左辺値であるため、次のようにします。

int (*func)(void);

そして、あなたprintfはこれでなければなりません:

printf("%d\n", func());

dlsymまた、標準 C に厳密に準拠するために、からの戻り値をキャストする必要があります。

func = (int (*)(void))dlsym(dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

ポインターは、関数へのvoid*ポインターを除く他のポインター型にサイレントにアップグレードできます。gcc -pedanticたとえば、キャストなしでは、「ISO C は関数ポインタと 'void *' の間の代入を禁止しています」と警告します。私は標準のコピーを手元に持っていません (しかし、このあたりの誰かが確かに持っています) ので、章と節を引用することはできませんが、caf はこの点で正しいです (caf に感謝します)。

また、 cdecl.orgをブックマークしたいとします。

于 2011-04-08T02:25:08.617 に答える
0

あなたがしようとしていることを実際に行うことはできません

しかし、それは int (func*)() でなければなりません

printf は func() である必要があります

ただし、すべてのパラメーターを関数ポインターとして dlsym に割り当てることはできません

ヒント....関数ポインタ「func」は単なるポインタであり、状態を持たず、単なるメモリアドレスです

func と呼ばれるポインターを作成しているため、func ..... と呼ばれる関数を提供しないでください。関数 "int test_function(){ return 42; } を作成できます

次に、メインで func = test_function; に進みます。関数ポインターを使用してテストするだけです

于 2011-04-08T02:19:47.177 に答える
0

する必要はありません*func()

printf("%d\n", func());

func() は int を返すため、整数の逆参照 (*) を取得しようとするため、問題ありません。

演算子の優先順位を見てください (リンク)

于 2011-04-08T02:22:11.203 に答える