Как мне получить / связать внешние функции в C или C ++? - PullRequest
3 голосов
/ 06 января 2009

РЕДАКТИРОВАТЬ: Я полагаю, я должен уточнить, если это имеет значение. Я использую AIX Unix, поэтому я использую компиляторы VAC, а не компиляторы GNU. Конец редактирования

<ч />

Я довольно ржавый в C / C ++, так что простите, если это простой вопрос.

Я бы хотел взять общие функции из нескольких моих программ на C и поместить их в общие библиотеки или общие объекты. Если бы я делал это в Perl, я бы поместил свои сабвуферы в модуль Perl и использовал этот модуль при необходимости.

Для примера, скажем, у меня есть эта функция:

int giveInteger()
{
    return 1034;
}

Очевидно, что это не реальный пример, но если бы я хотел поделиться этой функцией, как бы я поступил?

Я почти уверен, что у меня есть 2 варианта:

  1. Поместите мою разделяемую функцию в файл и сделайте так, чтобы она компилировалась с моей основной программой во время компиляции. Если я когда-нибудь внесу изменения в свою общую функцию, мне придется перекомпилировать основную программу.
  2. Поместите мою разделяемую функцию в файл и скомпилируйте ее как разделяемую библиотеку (если у меня правильные условия), и моя основная программа ссылается на эту разделяемую библиотеку. Любые изменения, которые я делаю в моей общей библиотеке (после ее компиляции), будут интегрированы в мою основную программу во время выполнения без перекомпиляции моей основной программы.

Правильно ли я считаю?

Если так, как я могу выполнить один или оба этих метода? Я много искал, и мне кажется, что я нашел информацию о том, как у меня есть своя собственная программа, связывающаяся с чужой общей библиотекой, но не о том, как создавать свои собственные общие функции и компилировать их так, чтобы я мог использовать их в своей собственной программе .

Большое спасибо!

Brian

<ч />

РЕДАКТИРОВАТЬ:

Заключение

Спасибо всем за вашу помощь! Я подумал, что добавлю в этот пост то, что работает для меня (для динамических разделяемых библиотек в AIX), чтобы другие могли извлечь выгоду:

Я компилирую свои общие функции:

xlc -c sharedFunctions.c -o sharedFunctions.o

Затем сделайте его общим объектом:

xlc -qmkshrobj -qexpfile=exportlist sharedFunctions.o
xlc -G -o libsharedFunctions.so sharedFunctions.o  -bE:exportlist

Затем свяжите его с другой программой:

xlc -brtl -o mainProgram mainProgram.c  -L. -lsharedFunctions

И еще один комментарий помог мне найти эту ссылку, которая также помогла: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/proguide/ref/compile_library.htm

Еще раз спасибо всем, кто помог мне!

Ответы [ 3 ]

6 голосов
/ 06 января 2009

Да, вы правы. Первый называется статической библиотекой , а второй называется общей библиотекой , потому что код не привязан к исполняемому файлу во время компиляции, но каждый раз снова, когда ваша программа загружается ,

Статическая библиотека

Скомпилируйте код вашей библиотеки следующим образом:

gcc -c *.c

-c говорит программе не связывать объектный файл, а просто оставляет вам объектные файлы для каждого .c файла, который был скомпилирован. Теперь заархивируйте их в одну статическую библиотеку:

ar rcs libmystuff.a *.o 

man ar скажет вам, что означают опции rcs. Теперь libmystuff.a - это a rchive файл (вы можете открыть его с помощью некоторых просмотрщиков zip-файлов), который содержит эти объектные файлы вместе с индексом символов для каждого объектного файла. Вы можете связать его с вашей программой:

gcc *.c libmystuff.a -o myprogram

Теперь ваша программа готова. Обратите внимание, что порядок появления статических библиотек в команде имеет значение. Смотрите мой Порядок ссылок ответ.

Общая библиотека

Для общей библиотеки вы создадите свою библиотеку с

gcc -shared -o libmystuff.so *.c

Это все, что нужно, libmystuff.so теперь является s hared o bject файлом. Если вы хотите связать программу с ней, вы должны поместить ее в каталог, указанный в файле /etc/ld.so.conf, или заданный переключателем -L для GCC или указанный в переменной LD_LIBRARY_PATH. При связывании вы вырезаете префикс lib и суффикс .so из имени библиотеки, которое вы сообщаете gcc.

gcc -L. -lmystuff *.c -o myprogram

Внутренне, gcc просто передаст ваши аргументы компоновщику GNU. Вы можете увидеть, какие аргументы он передает, используя опцию -###: Gcc напечатает точные аргументы, заданные для каждого подпроцесса.

Подробную информацию о процессе компоновки (как некоторые вещи выполняются внутри) смотрите в моем Linux GCC linker ответ.

4 голосов
/ 06 января 2009

У вас есть третий вариант. В общем, ваш компилятор C ++ должен быть в состоянии связывать подпрограммы на Си. Необходимые параметры могут варьироваться от компилятора к компилятору, так что R ваш прекрасный M, но в принципе вы должны быть в состоянии скомпилировать с g ++, как здесь:

$ g++ -o myapp myapp.cpp myfunc.c giveint.c

... или скомпилировать отдельно

$ gcc -c myfunc.c
$ gcc -c giveint.c
$ g++ -c myapp.cpp
$ g++ -o myapp myapp.o myfunc.o

Вам также необходимо включить объявление функций; вы делаете это в C ++ как

extern "C" {
    int myfunc(int,int);
    int giveInterger(void);
}
0 голосов
/ 07 января 2009

Необходимо различать перекомпиляцию и перекомпоновку.

Если вы поместите giveInteger() в отдельную (архивную) библиотеку, а затем измените ее позже, вам (очевидно) потребуется перекомпилировать исходный файл, в котором он определен, и relink all программы, которые его используют; но вам не нужно будет перекомпилировать таких программ [1].

Для разделяемой библиотеки вам необходимо перекомпилировать и заново связать библиотеку; но вам не придется перепривязывать или перекомпилировать какие-либо программы, которые его используют.

Сборка общих библиотек C ++ в AIX была сложной; вам нужно было использовать скрипт оболочки makeC ++ SharedLib. Но с VAC 5.0 и 6.0 это стало довольно просто. Я считаю, что все, что вам нужно сделать, это [2]:

xlC -G -o shr.o giveInteger.cc
xlC -o myapp main.cc shr.o

[1] Если вы напишите правильный Makefile (что рекомендуется), все это произойдет автоматически при вводе make.

[2] В AIX есть некоторая особенность, которая может усложнить ситуацию: по умолчанию разделяемые библиотеки загружаются в память и «залипают» там до последующей перезагрузки. Таким образом, вы можете пересобрать shr.o, перезапустить программу и наблюдать «старую» версию выполняемой библиотеки. Чтобы предотвратить это, обычной практикой является сделать мир нечитаемым shr.o:

chmod 0750 shr.o
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...