Как язык расширяет себя?

Я изучаю C ++, и я только начал изучать некоторые из Qtвозможности кодирования программ GUI. Я задал себе следующий вопрос:

Как C ++, который ранее не имел синтаксиса, способного запрашивать у ОС окно или способ связи через сети (с API, которые я не совсем понимаю, я признаю) внезапно получает такие возможности? через сами библиотеки написанные на C ++? Все это кажется мне ужасно круглым. Какие инструкции C ++ вы могли бы придумать в этих библиотеках?

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

206

Решение

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

Например, в случае Операционная система Windows предоставляет так называемый WIN32 API для приложений, работающих в Windows. Библиотека Qt использует этот API для предоставления приложениям, использующим Qt, свой собственный API. Вы используете Qt, Qt использует WIN32, WIN32 использует более низкие уровни операционной системы Windows и т. Д. До тех пор, пока в оборудовании не появятся электрические сигналы.

190

Другие решения

Вы правы в том, что в целом библиотеки не могут сделать ничего невозможного.

Но библиотеки не должны быть написаны на C ++, чтобы их можно было использовать в программе на C ++. Даже если они написаны на C ++, они могут использовать другие библиотеки, не написанные на C ++. Таким образом, тот факт, что C ++ не предоставил никакого способа сделать это, не препятствует тому, чтобы это было добавлено, пока есть немного способ сделать это за пределами C ++.

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

59

C и C ++ имеют 2 свойства, которые позволяют всю эту расширяемость, о которой говорит OP.

  1. C и C ++ могут получить доступ к памяти
  2. C и C ++ могут вызывать ассемблерный код для инструкций не на языке C или C ++.

В ядре или в базовой платформе в незащищенном режиме периферийные устройства, такие как последовательный порт или дисковод, отображаются в карту памяти так же, как и ОЗУ. Память представляет собой серию переключателей, и при переключении периферийных устройств вы получаете последовательный порт или диск для выполнения полезных задач.

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

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

Существует еще один уровень API, который намного полезнее системного вызова. Взять, к примеру, malloc. Это не только вызовет систему для получения больших блоков памяти, но и будет управлять этой памятью, ведя весь бухгалтерский учет того, что происходит.

Win32 API обертывают некоторые графические функции общим набором виджетов платформы. Qt продвигается дальше, оборачивая Win32 (или X Windows) API кроссплатформенным способом.

Фундаментально, хотя компилятор C превращает код C в машинный код, и, поскольку компьютер предназначен для использования машинного кода, следует ожидать, что C сможет выполнить общий доступ lions или то, что может сделать компьютер. Все, что делают библиотеки-обертки, это делает тяжелую работу за вас, чтобы вам не пришлось это делать.

42

Языки (как C ++ 11) являются технические характеристики, на бумаге, как правило, написано на английском языке. Заглянуть внутрь последние C ++ 11 черновик (или купить дорого окончательная спецификация от вашего поставщика ISO).

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

Ваша реализация C ++ в целом работает над некоторой операционной системой и взаимодействует с ней (используя некоторые конкретная реализация код, часто в какой-то системной библиотеке). Как правило, это общение осуществляется через системные вызовы. Посмотрите, например, в Системные вызовы (2) список системных вызовов, доступных на Ядро Linux.

С прикладной точки зрения системный вызов — это элементарная машинная инструкция, такая как SYSENTER на x86-64 с некоторыми соглашениями (ABI)

На моем рабочем столе Linux библиотеки Qt находятся выше X11 клиентские библиотеки, взаимодействующие с сервером X11 Xorg через X протоколы Windows.

В Linux используйте ldd в вашем исполняемом файле, чтобы увидеть (длинный) список зависимостей от библиотек. использование pmap на вашем рабочем процессе, чтобы увидеть, какие из них «загружены» во время выполнения. Кстати, в Linux ваше приложение, вероятно, использует только бесплатное программное обеспечение, вы можете изучить его исходный код (от Qt до Xlib, libc, … ядра), чтобы лучше понять, что происходит

22

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

Системные вызовы — это низкоуровневый способ использования возможностей операционной системы, но он может быть сложным и громоздким в использовании, поэтому его часто «оборачивают» в API, чтобы вам не приходилось иметь с ними дело напрямую. Но под всем, что бы вы ни делали, включая ресурсы, связанные с O / S, будут использоваться системные вызовы, включая печать, сетевые подключения, сокеты и т. Д.

В случае Windows Microsoft Windows имеет свой GUI, фактически записанный в ядро, поэтому существуют системные вызовы для создания окон, рисования графики и т. Д. В других операционных системах GUI может не являться частью ядра, и в этом случае насколько я знаю, не было бы никаких системных вызовов для вещей, связанных с GUI, и вы могли бы работать только на еще более низком уровне с любой доступной графикой низкого уровня и входными связанными вызовами.

19

Хороший вопрос. Каждый новый разработчик C или C ++ имеет это в виду. Я предполагаю стандартную машину x86 для остальной части этого поста. Если вы используете компилятор Microsoft C ++, откройте блокнот и введите его (назовите файл Test.c)

int main(int argc, char **argv)
{
return 0
}

А теперь скомпилируйте этот файл (используя командную строку разработчика) cl Test.c /FaTest.asm

Теперь откройте Test.asm в своем блокноте. То, что вы видите, это переведенный код — C / C ++ переведен на ассемблер. Ты понял намек?

_main   PROC
push    ebp
mov ebp, esp
xor eax, eax
pop ebp
ret 0
_main   ENDP

Программы на C / C ++ предназначены для работы на металле. Это означает, что они имеют доступ к оборудованию более низкого уровня, что облегчает использование возможностей оборудования. Скажем, я собираюсь написать библиотеку C getch () на компьютере с архитектурой x86.

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

_getch proc
xor AH, AH
int 16h
;AL contains the keycode (AX is already there - so just return)
ret

Я запускаю его с помощью ассемблера и генерирую .OBJ — назовите его getch.obj.

Затем я пишу программу на C (я ничего не включаю)

extern char getch();

void main(int, char **)
{
getch();
}

Теперь назовите этот файл — GetChTest.c. Скомпилируйте этот файл, передав getch.obj. (Или скомпилируйте индивидуально в .obj и LINK GetChTest.Obj и getch.Obj вместе, чтобы создать GetChTest.exe).

Запустите GetChTest.exe, и вы обнаружите, что он ожидает ввода с клавиатуры.

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

Оба языка поддерживают ключевое слово __asm, что означает, что вы также можете смешивать код на ассемблере. Изучение C и C ++ сделает вас лучшим программистом в целом.

Нет необходимости всегда связываться с Ассемблером. Я упоминал об этом, потому что думал, что это поможет вам лучше понять. В основном, большинство таких библиотечных вызовов используют системные вызовы / API, предоставляемые операционной системой (операционная система, в свою очередь, выполняет взаимодействие с оборудованием).

15

Как работает C ++ … вдруг получить такие возможности через библиотеки
сами написали на С ++?

Нет ничего волшебного в использовании других библиотек. Библиотеки — это простые большие пакеты функций, которые вы можете вызывать.

Считайте, что вы пишете такую ​​функцию

void addExclamation(std::string &str)
{
str.push_back('!');
}

Теперь, если вы включите этот файл, вы можете написать addExclamation(myVeryOwnString);, Теперь вы можете спросить: «Как в C ++ вдруг появилась возможность добавлять восклицательные знаки в строку?» Ответ прост: вы написали функцию для этого, а затем вызвали ее.

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

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

10

Ключ — это возможность операционной системы предоставлять API и подробное описание того, как использовать этот API.

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

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

8
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector