Как мне создать источник / связать внешние функции на C или C ++?

StackOverflow https://stackoverflow.com/questions/417876

  •  03-07-2019
  •  | 
  •  

Вопрос

Редактировать: Полагаю, мне следует уточнить, на случай, если это имеет значение.Я использую AIX Unix box, поэтому я использую компиляторы VAC - без компиляторов gnu.Конечное редактирование


Я довольно плохо разбираюсь в C / C ++, так что простите меня, если это простой вопрос.

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

В качестве примера, допустим, у меня есть эта функция:

int giveInteger()
{
    return 1034;
}

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

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

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

Прав ли я в этом рассуждении?

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

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

Брайан


Редактировать:

Заключение

Спасибо всем за вашу помощь!Я подумал, что хотел бы добавить в этот пост то, что работает у меня (для динамических разделяемых библиотек в 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

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

Это было полезно?

Решение

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

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

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

gcc -c *.c

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

ar rcs libmystuff.a *.o 

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

gcc *.c libmystuff.a -o myprogram

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

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

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

gcc -shared -o libmystuff.so *.c

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

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

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

Для получения подробной информации о процессе компоновки (как некоторые вещи выполняются внутри компании), просмотрите мой Компоновщик Linux GCC отвечай.

Другие советы

У вас есть третий вариант.В общем, ваш компилятор C ++ должен быть способен связывать подпрограммы 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);
}

Вам нужно различать перекомпиляцию и повторную компоновку.

Если вы поставите giveInteger() в отдельную (архивную) библиотеку, а затем измените ее позже, вам (очевидно) потребуется перекомпилировать исходный файл, в котором она определена, и повторная ссылка все программы, которые его используют;но вам не нужно будет перекомпилировать такие программы [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 world-нечитаемым:

chmod 0750 shr.o
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top