определить main () (точку входа) для библиотеки необходимо? - PullRequest
0 голосов
/ 06 марта 2020

Я был после этого урока о том, как создать библиотеку stati c, и автор определяет функцию (для библиотеки) в lib_mylib.c как:

#include <stdio.h> //Although I use <iostream>
void fun(void) 
{ 
  printf("fun() called from a static library"); 
}

Он идет дальше и просто компилирует это как:

 gcc -c lib_mylib.c -o lib_mylib.o 

Обратите внимание, что не определено main(), которое будет точкой входа по умолчанию для программ, но он ничего не упоминает об этом, и мне кажется, что это логично потому что библиотеки - это не то, что мы запускаем, а то, что мы включаем для запуска наших программ, и, следовательно, наш исходный код должен иметь функцию main().

Но minGW g++ compiler says this:

c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status

и в соответствии с этим вопросом Я не определяю основную, а ошибка действительно кажется go прочь, как только я определю функцию main (). Может кто-нибудь объяснить мне, что происходит под капотом, и устранить эту путаницу.

PS: Было бы очень полезно, если бы вы упомянули какие-либо ресурсы для такого обучения. Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 06 марта 2020

Отвечая на ваш вопрос: Нет, вам не нужно определять основную точку входа для библиотеки.

Ключом здесь является опция -c от g cc , который пропускает этап связывания.

Из руководства g cc

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

Вы можете ознакомиться с другими g cc options здесь .

Форма оценки вывод вашей ошибки, вы, вероятно, забыли добавить эту опцию, потому что вы получаете ошибку компоновщика.

PS: я считаю, что учебник, который вы читаете, имеет хорошее вводное объяснение этой топи c.

EDIT

Ваша проблема связана с разницей между компиляцией ссылок.

C программы написаны в удобочитаемом исходном коде, который не исполняется напрямую компьютером. Требуется трехэтапный процесс для преобразования исходного кода в исполняемый код. Эти три шага: Предварительная обработка, компиляция и компоновка

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

Компиляция - Измененный исходный код компилируется в двоичный объектный код. Этот код еще не является исполняемым.

Связывание - объектный код объединяется с необходимым вспомогательным кодом для создания исполняемой программы. Этот шаг обычно включает добавление любых необходимых библиотек.

Здесь вы можете найти интересное руководство по основам c C концепций.

1 голос
/ 06 марта 2020

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

Чтобы скомпилировать библиотеку, необходимо скомпилировать в позиционно-независимый код .

gcc -c -fpic lib_mylib.c -o lib_mylib.o

Это не даст вам ошибок при связывании. Затем, создавая фактическую разделяемую библиотеку из этого объектного файла, вам нужно выполнить:

gcc -shared -o lib_mylib.so lib_mylib.o

Скажите, пожалуйста, не приводит ли это к ожидаемым результатам.

...