Как реализованы библиотеки, которые добавляют не-c-функциональность в C? - PullRequest
4 голосов
/ 10 февраля 2009

Может кто-нибудь объяснить мне, как в C добавлена ​​дополнительная функциональность?

Например, C не имеет функции вывода, поэтому вы можете использовать printf (), включая stdio.h, C не знает, как открыть MessageBox, поэтому вы включаете и используете MessageBox () и т. Д.

Но как реализован этот функционал?

Вам нужно каким-то образом использовать ассемблер и получить доступ к видеопамяти, чтобы иметь выход или что-то подобное?

Я знаю, что MessageBox (), например, является частью WinAPI, но как он реализован (хотя WinAPI реализован в C)?

Ответы [ 5 ]

7 голосов
/ 10 февраля 2009

Любые функциональные возможности, взаимодействующие с системой, выполняются через механизм системных вызовов. По сути, это обеспечивает интерфейс между вашим кодом и операционной системой. Упомянутые вами библиотечные функции объединяют некоторые удобные функции с различными системными вызовами, чтобы облегчить взаимодействие вашего кода с системой на более высоком уровне. Однако вы можете написать код, чтобы сделать это напрямую. Для получения дополнительной информации посмотрите функции syscall и ioctl . В Windows существует больше системных вызовов, и они разбросаны по разным библиотекам в Windows API . Это доктор. Статья Добба о системных вызовах Windows более детально

3 голосов
/ 10 февраля 2009

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

Таким образом, большая часть общения с внешним миром - такими устройствами, как ваша видеокарта, сетевая карта и т. Д. - в основном сводится к чтению или записи в области волшебной памяти.

(Это небольшое упрощение, есть несколько других вещей, которые может делать ЦП - порты ввода-вывода, в которые он может читать / записывать числа и т. Д .; они не доступны напрямую из стандартного C, и, как правило, библиотеки C, которые предоставляют такой функционал будет иметь соответствующий код, написанный на ассемблере, но давайте сейчас его выполним).

Аппаратные драйверы, написанные на C, обычно объявляют struct s, которые описывают расположение отображаемых в памяти областей, используя знакомые типы C, получают адреса соответствующих областей, выполняют соответствующие приведения, а затем просто используют полученные указатели, как и любые другие. .

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

2 голосов
/ 10 февраля 2009

Для части printf - это часть стандартной библиотеки C, которая является частью C. Таким образом, реализация вашего компилятора C или стандартной библиотеки C может использовать все возможные приемы, чтобы она работала.

Давайте рассмотрим простой пример того, как такая функция может быть реализована в Unix. Возьми putchar (здесь упрощенно - ничего не возвращая). Он выводит один символ на стандартный вывод, который имеет дескриптор файла номер 1. Операционная система предоставляет функцию, называемую «запись». Программа может записывать в дескриптор файла. Итак, putchar может использовать эту функцию:

void putchar(int c) {
    unsigned char cc = c;
    write(1, &cc, 1);
}

Запишет 1 байт в дескриптор файла 1. Функция записи сообщит операционной системе об этом желании:

void write(int fd, void * ptr, size_t size) {
    asm("....."
        "int 0x80"); 
}

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

Это грубый план. Конечно, есть еще кое-что (putchar может буферизовать вывод перед выполнением системного вызова ...). Но в принципе так работает.

Функция MessageBox в конце также вызовет некоторый системный вызов, который передает управление ядру Windows тем или иным способом, аналогичным приведенному выше объяснению.

1 голос
/ 10 февраля 2009

Сначала у вас есть компилятор C, который соответствует стандарту ANSI C. Это сам язык, без библиотек.

Тогда у вас есть стандартная библиотека, в которой вы найдете функцию printf, которую вы упомянули. Это построено с использованием C и ASM и зависит от платформы. Например, во встроенной платформе printf будет печатать символы на последовательном порту или на ЖК-дисплее. Поэтому необходимо использовать специфический для платформы код. Однако интерфейс является общим для всех платформ.

Нечто подобное происходит со сторонними библиотеками, такими как WinAPI.

0 голосов
/ 10 февраля 2009

Часто библиотеки пишутся на "C". Большая часть API Win32 написана на C. Есть несколько вещей, которые вы не можете выразить напрямую в C, такие как 'syscall', 'int' и чтение / запись в порты io.

Взгляните на K & R , они фактически реализуют некоторые системные библиотеки в книге.

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