GCC Динамическая задача создания библиотеки - PullRequest
2 голосов
/ 26 апреля 2010

Я новичок в Linux, при компиляции с динамической библиотекой я получаю ошибку ошибки сегментации.

У меня есть два файла

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. -о прога

Но когда я запускаю сгенерированный исполняемый файл, я получаю ошибку SegmentationFault.

Когда я проверял заголовок прог с ldd, он показывает

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

Может кто-нибудь сказать, в чем проблема

Ответы [ 3 ]

6 голосов
/ 26 апреля 2010

Вы не звоните в ctest1.c или ctest2.c. Вместо этого вы создаете указатели на функции ctest1 и ctest2 в файле prog.c, который не инициализируете, поэтому он вызывает ошибку сегментации при попытке вызвать их.

Вам необходимо объявить свои функции, чтобы prog.c мог их видеть, а затем связать prog.c с библиотеками (возможно, с помощью параметра -l для gcc).

#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
1 голос
/ 26 апреля 2010

Попробуйте после использования информации, которую 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, так как это может сделать вашу библиотеку менее переносимой) Не могло быть больно иметь его, но для простоты я опустил его в приведенных выше строках.

0 голосов
/ 26 апреля 2010

.so библиотеки в linux динамически связаны. Вам нужно будет открыть файл .so с помощью dlopen () в prog.c, найти символы, а затем вызвать ctest1 () и ctest2 () с помощью указателей на функции.

...