2

Linux は初めてですが、ダイナミック ライブラリを使用してコンパイルしているときに、segmentationfault エラーが発生します。

私は2つのファイルを持っています

ctest1.c

void ctest1(int *i)
{ 
   *i =10;
}

ctest2.c

void ctest2(int *i)
{ 
   *i =20;
}

次のコマンドを使用して、両方のファイルを libtest.so という名前の共有ライブラリにコンパイルしました

  gcc -shared -W1,-soname,libtest.so.1 -o libtest.so.1.0.1 ctest1.o ctest2.o -lc

そして、このライブラリによってエクスポートされた関数を使用する別のプログラム prog.c を作成しました。

prog.c

#include <stdio.h>

void (*ctest1)(int*);
void (ctest2)(int*);


int main()
{
  int a;

  ctest1(&a);

  printf("%d",a);

  return 0;

}

そして、次のコマンドで実行可能ファイルをビルドしたとき

gcc -Wall prog.c -L. -o プログラム

しかし、生成された実行可能ファイルを実行すると、SegmentationFault エラーが発生します。

ldd で prog のヘッダーを確認すると、次のように表示されます

linux-vdso.so.1 => (0x00007f99dff000) libc.so.6 => /lib64/libc.so.6 (0x0007feeaa8c1000) /lib64/ld-linux-x86-64.so.2 (0x00007feeaac1c000)

誰かが何が問題なのか教えてもらえますか

4

3 に答える 3

6

ctest1.c または ctest2.c を呼び出していません。代わりに、prog.c で ctest1 および ctest2 関数ポインターを作成していますが、これは初期化していないため、それらを呼び出そうとするとセグメンテーション フォールトが発生します。

prog.c が関数を認識できるように関数を宣言してから、prog.c をライブラリにリンクする必要があります (おそらく gcc の -l オプションを使用します)。

#include <stdio.h>

extern void ctest1(int*);
extern void ctest2(int*);


int main()
{
  int a;

  ctest1(&a);

  printf("%d",a);

  return 0;

}

そして次のようなもの:

gcc -Wall -L. -ltest prog.c -o prog
于 2010-04-26T04:45:23.240 に答える
1

WhirlWind から提供された情報を使用してから、これを試してください (「#」で始まる行はコメントです。入力する必要はありません)。

# Ensure that any shared objects you use are available in the current directory.
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

# Compile the library with a real name of "libctest.so.1.0.1"
# and a soname of "libctest.so.1".
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0.1 ctest1.o ctest2.o

# Create a symbolic link with soname as the name that points to the library.
# (libctest.so.1 -> libctest.so.1.0.1)
/sbin/ldconfig -v -n .

# Create a symbolic link using the "linker name" that points to the newly
# created library.
ln -sf libctest.so.1 libctest.so

# Compile your program.
gcc -Wall -L. prog.c -o prog -l ctest

# Run your program (it won't work without setting LD_LIBRARY_PATH because
# it won't be able to find your library).
./prog

それは私のために働いた。一見大変な作業ですが、試行錯誤を繰り返すうちに、ほぼ日常的な作業になっていると思います。

詳細については、http://www.ibm.com/developerworks/library/l-shobj/ を参照してください。:)

編集:多くのチュートリアルが -fPIC オプションを使用して位置に依存しないコードを生成することを提案しているように思われることをほとんど忘れていました (-fpic と混同しないでください。結果のライブラリの移植性が低下する可能性があるためです)。持っていても害はありませんが、簡単にするために、上記の行から省略しました。

于 2010-04-26T05:57:29.343 に答える
-4

Linux の .so ライブラリは動的にリンクされます。prog.c で dlopen() を使用して .so ファイルを開き、シンボルを見つけてから、関数ポインターを介して ctest1() および ctest2() を呼び出す必要があります。

于 2010-04-26T05:02:32.093 に答える