Есть ли смысл изучать низкоуровневое программирование WinAPI?

Имеет ли смысл, имея все блаженство, управляемое C#, вернуться к Окне программирования Петцольда и попытаться создать код с чистым WinAPI?

Что можно извлечь из этого? Разве это не слишком устарело, чтобы быть полезным?

Ответов (22)

Решение

Этот вопрос граничит с религиозным :) Но все равно выскажу свои мысли.

Я действительно вижу ценность в изучении Win32 API. Большинство, если не все библиотеки графического интерфейса (управляемые или неуправляемые) приводят к вызовам Win32 API. Даже самые тщательные библиотеки не охватывают 100% API, и, следовательно, всегда есть пробелы, которые необходимо заполнить прямыми вызовами API или вызовом P /. Некоторые имена оболочек вокруг вызовов API имеют имена, аналогичные именам базовых вызовов API, но эти имена не совсем самодокументируются. Таким образом, понимание базового API и используемой в нем терминологии поможет понять API-интерфейсы оболочки и то, что они на самом деле делают.

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

Ваше здоровье!

Простой ответ, ДА.

Я придерживался стандарта C/C++ в течение многих лет, прежде чем изучать Win32 API, и, откровенно говоря, «изучение Win32 API» - не лучший технический опыт в моей жизни.

С одной стороны, Win32 API - это круто. Это похоже на расширение стандартного API C (кому нужно, fopen когда вы можете его иметь CreateFile . Но я думаю, что UNIX / Linux / WhateverOS имеют те же гизмо-функции. В любом случае, в Unix / Linux у них есть «Все - файл». В Windows , у них есть "Все ... Окно" (без шуток! Смотрите CreateWindow !).

С другой стороны, это устаревший API. Вы будете иметь дело с чистым C и чистым C безумием.

  • Это то же самое, что указать структуре ее собственный размер, чтобы передать void *указатель на некоторую функцию Win32.
  • Обмен сообщениями тоже может сбивать с толку: смешивание объектов C++ с окнами Win32 приводит к очень интересным примерам проблем с курицей или яйцом (забавные моменты, когда вы пишете своего рода delete this ;метод класса).
  • Создание подкласса WinProc, когда вы более знакомы с наследованием объектов, - это ошеломляюще и менее чем оптимально.
  • И, конечно же, есть радость от « Почему в этом мире гидроразрыва пласта они сделали это именно так? », Когда вы слишком часто ударяете по клавиатуре головой и возвращаетесь домой с выгравированными на лбу клавишами просто потому, что кто-то посчитал более логичным написать API, позволяющее изменять цвет «окна», не изменяя одно из его свойств, а запрашивая его у его родительского окна.
  • и т.п.

В последнюю очередь ( три руки ??? ) учтите , что некоторые люди, работающие с устаревшими API-интерфейсами, сами используют устаревшие стили кода. В тот момент, когда вы слышите « constэто для чайников » или « Я не использую пространства имен, потому что они уменьшают скорость выполнения », или даже лучше « Эй, кому нужен C++? Я пишу код на своем собственном бренде объектно-ориентированного C !!! «(Без шуток ... В профессиональной среде, и результат был просто зрелищным ...), вы почувствуете страх перед гильотиной .

Так что ... В общем, это интересный опыт.

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

Перечитав этот пост, я понял, что его можно рассматривать как чрезмерно негативный. Нет.

Иногда интересно (а также досадно) узнать, как все работает под капотом. Вы поймете, что, несмотря на огромные (невозможные?) Ограничения, команда Win32 API проделала замечательную работу, чтобы убедиться, что все, от вашей «старой программы Win16» до вашего «последнего приложения Win64 over-the-top», может работать вместе, в прошлом, сейчас и в будущем.

Вопрос в том, действительно ли вы этого хотите?

Потому что потратить недели на то, что можно было бы сделать (и сделать лучше) с помощью другого более высокоуровневого и / или объектно-ориентированного API, может быть довольно демотивационным (реальный жизненный опыт: 3 недели для Win API, против 4 часов из трех). другие языки и / или библиотеки).

В любом случае, вы найдете блог Рэймонда Чена очень интересным из-за его взгляда изнутри как на Win API, так и на его эволюцию с годами:

https://blogs.msdn.microsoft.com/oldnewthing/

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

На то, чтобы научиться правильно реализовывать вызовы собственных API-интерфейсов, требуется много времени и усилий, а возвращаемое значение того не стоит. Я бы предпочел потратить время на изучение какой-нибудь новой технологии или фреймворка, которые сделают вашу жизнь проще, а программирование - менее болезненным. Не устаревшие библиотеки COM десятилетней давности, которые больше никто не использует (извините пользователей COM).

Пожалуйста, не забивай меня камнями за такой вид. Я знаю, что у многих здесь инженеров действительно любопытные души, и нет ничего плохого в том, чтобы узнать, как все работает. Любопытство - это хорошо и действительно помогает пониманию. Но с управленческой точки зрения я бы предпочел потратить неделю на изучение того, как разрабатывать приложения для Android, чем на то, как называть OLE или COM.

Ценность, которую вы получите от изучения Win32 API (помимо общего понимания, которое вы получите, узнав о том, как сочетаются друг с другом элементы машины), зависит от того, чего вы пытаетесь достичь. Большая часть Win32 API была хорошо обернута в классы библиотеки .NET, но не все. Если, например, вы хотите серьезно заняться программированием звука, эта часть Win32 API станет отличным предметом для изучения, поскольку из классов .NET доступны только самые основные операции. В последний раз я проверял, что даже управляемая библиотека DirectX DirectSound была ужасной.


Рискуя бессовестную саморекламу ....

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

Собственные API-интерфейсы - это «настоящие» API-интерфейсы операционной системы. Библиотека .NET - это (за некоторыми исключениями) не более чем причудливая оболочка вокруг них. Так что да, я бы сказал, что любой, кто может понять .NET со всей его сложностью, может понять относительно приземленные вещи, такие как общение с API, без помощи посредника.

Просто попробуйте сделать DLL Injection из управляемого кода. Это невозможно. Вам придется написать собственный код для этого, для настройки окон, для реального создания подклассов и еще десятка других вещей.

Так что да: вы должны (должны) знать и то, и другое.

Изменить: даже если вы планируете использовать P / Invoke.

Изучение C или языка более низкого уровня определенно может быть полезным. Однако я не вижу очевидных преимуществ в использовании неуправляемого WinAPI.

Абсолютно. Когда никто не знает низкого уровня, кто будет обновлять и писать языки высокого уровня? Кроме того, когда вы понимаете материал низкого уровня, вы можете писать более эффективный код на языке более высокого уровня, а также более эффективно отлаживать.

Важно знать, что доступно в Windows API. Я не думаю, что вам нужно проверять код с его помощью, но вы должны знать, как это работает. .NET Framework содержит множество функций, но не предоставляет эквивалентов управляемого кода для всего Windows API. Иногда вам нужно подойти немного ближе к металлу, и знание того, что там внизу и как он себя ведет, даст вам лучшее понимание того, как его использовать.

Изучение нового языка программирования или технологии происходит по одной из трех причин:
1. Потребность: вы начинаете проект по созданию веб-приложения и ничего не знаете об ASP.NET
2. Энтузиазм: вам очень нравится ASP.NET MVC. почему бы не попробовать это?
3. Свободное время: да у кого оно есть.

Лучшая причина узнать что-то новое - это потребность. Если вам нужно сделать что-то, чего не может сделать .NET framework (например, производительность), то WinAPI - ваше решение. А пока мы заняты изучением .NET.

Аналогия: если вы строите машины для жизни (программирование), то очень уместно знать, как работает движок (Win32).

Я видел низкоуровневый код Windows API ... это неприятно ... Хотел бы я от него отучиться. Я думаю, что полезно изучать низкий уровень, как в C, поскольку вы лучше понимаете архитектуру оборудования и то, как все это работает. Изучение старого Windows API ... Я думаю, что этот материал можно оставить людям в Microsoft, которым, возможно, потребуется изучить его для создания языков и API более высокого уровня ... они создали его, пусть страдают с этим ;-)

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

Для большинства задач на рабочем столе вам не нужно знать Win32, однако в .NET есть ОЧЕНЬ много Win32, но это связано с затратами, которые в конечном итоге могут составить менее 1% вашего приложения.

Поддержка USB, поддержка HID, Windows Media Foundation просто у меня в голове. Есть много интересных API Vista, доступных только из Win32.

Вы окажете себе большую услугу, научившись взаимодействовать с Win32 API, если вы занимаетесь программированием на рабочем столе, потому что, когда вам действительно нужно вызвать Win32, а вы это сделаете, вы не будете тратить недели на то, чтобы чесать голову.

Предполагая, что вы создаете приложения, ориентированные на Windows:

  • может быть полезно понять более низкие уровни системы - как они работают, как ваш код взаимодействует с ними (даже если только косвенно), и где у вас есть дополнительные параметры, которые недоступны в абстракциях более высокого уровня
  • бывают случаи, когда ваш код может быть не таким эффективным, высокопроизводительным или достаточно точным для ваших требований
  • Однако во все большем количестве случаев такие люди, как мы (которые никогда не изучали «неуправляемое кодирование»), смогут осуществить программирование, которое мы пытаемся сделать, без «изучения» Win32.
  • Кроме того, существует множество сайтов, которые предоставляют рабочие образцы, фрагменты кода и даже полнофункциональный исходный код, который вы можете «использовать» (заимствовать, использовать плагиат - но убедитесь, что вы соблюдаете все лицензии на повторное использование или авторские права!) Для заполнения во всех пробелах, которые не обрабатываются библиотеками классов .NET framework (или библиотеками, которые вы можете загрузить или лицензировать).
  • Если вы можете выполнять необходимые подвиги, не возясь с Win32, и вы хорошо справляетесь с разработкой хорошо сформированного, читаемого управляемого кода, то я бы сказал, что освоение .NET было бы лучшим выбором, чем расточительство. в двух очень разных средах.
  • Если вам часто нужно использовать те функции Windows, которые не получили должного охвата библиотек классов Framework, то во что бы то ни стало, приобретите необходимые навыки.
  • Я лично потратил слишком много времени, беспокоясь о «других областях» кодирования, которые я должен понимать для создания «хороших программ», но есть множество мазохистов, которые думают, что потребности и желания каждого подобны их собственным. Страдание любит компанию. :)

Предполагая, что вы создаете приложения для мира «Web 2.0», или это было бы столь же полезно / выгодно для пользователей * NIX и MacOS:

  • Придерживайтесь языков и компиляторов, ориентированных на максимальное количество кроссплатформенных сред.
  • чистый .NET в Visual Studio, очевидно, лучше, чем Win32, но разработка с использованием библиотек MONO, возможно, с использованием Sharp Develop IDE, вероятно, является даже лучшим подходом.
  • вы также можете потратить свое время на изучение Java, и эти навыки будут очень хорошо перенесены в программирование на C# (плюс код Java теоретически будет работать на любой платформе с соответствующей JRE). Я слышал, что Java больше похожа на «пиши один раз, отлаживай везде», но это, вероятно, так же верно (или даже больше, чем) C#.

Лично мне не очень нравится Win32 API, но есть смысл изучить его, поскольку API позволит больше контроля и эффективности с использованием графического интерфейса, чем язык, подобный Visual Basic, и я считаю, что если вы собираетесь зарабатывать на жизнь программное обеспечение для написания вы должны знать API, даже если вы не используете его напрямую. Это по причинам, аналогичным причинам, по которым полезно изучать C, например, почему strcpy занимает больше времени, чем копирование целого числа, или почему вы должны использовать указатели на массивы в качестве параметров функции вместо массивов по значению.

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

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

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

Я скажу так. Я не люблю программировать для Win32 API. Это может быть боль по сравнению с управляемым кодом. НО, я рад, что знаю это, потому что я могу писать программы, которые иначе я бы не смог. Я могу писать программы, которые не умеют другие люди. Кроме того, это дает вам больше информации о том, что ваш управляемый код делает за кулисами.

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

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

Даже на языках очень высокого уровня вы по-прежнему используете API. Почему? Что ж, не каждый аспект API был воспроизведен различными библиотеками, фреймворками и т. Д. Вам нужно изучать API до тех пор, пока он вам понадобится для выполнения того, что вы пытаетесь сделать. (И больше нет.)

Если вы планируете разработать кроссплатформенное приложение, то если вы используете win32, то ваше приложение может легко работать в Linux через WINE. В результате получается приложение, удобное в обслуживании. Это одно из преимуществ изучения win32.

Да, по нескольким причинам:

1) .net обертывает код Win32. .net обычно является лучшей системой для кодирования, но наличие некоторых знаний о нижележащем уровне Win32 (ой, WinAPI теперь, когда есть 64-битный код) укрепляет ваши знания о том, что на самом деле происходит.

2) в этой экономике лучше иметь какие-то преимущества перед другим парнем, когда вы ищете работу. Некоторый опыт WinAPI может предоставить вам это.

3) некоторые системные аспекты пока недоступны через платформу .net, и если вы хотите получить доступ к этим функциям, вам нужно будет использовать p / invoke (см. http://www.pinvoke.net для получения помощи). Наличие хотя бы небольшого количества опыта работы с WinAPI сделает ваши усилия по разработке p / invoke намного более эффективными.

4) (добавлено) Теперь, когда Win8 существует уже некоторое время, она все еще построена на основе WinAPI. iOS, Android, OS / X и Linux уже существуют, но WinAPI будет существовать еще много лет.

Это ответ на любой вопрос типа .. "имеет ли смысл изучать язык низкого уровня / api X, даже если есть язык более высокого уровня / api Y"

ДА

Вы можете загрузить свой ПК с Windows (или любую другую ОС) и задать этот вопрос в SO, потому что пара парней из Microsoft написала 16-битный ассемблерный код, который загружает вашу ОС.

Ваш браузер работает, потому что кто-то написал ядро ​​ОС на языке C, которое обслуживает все запросы вашего браузера.

Это касается языков сценариев.

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

Никакой API / язык на любом уровне абстракции не имеет значения, если нет лучшего, конкурирующего на том же уровне .

Другой взгляд на это: хороший пример из одной из книг Майкла Абраша: программисту AC было поручено написать функцию для очистки экрана. Поскольку C был лучшей (более высокоуровневой) абстракцией по сравнению с ассемблером и всем остальным, программист знал только C и знал его хорошо. Он постарался как мог - переместил курсор в каждое место на экране и очистил оттуда персонажа. Он оптимизировал цикл и убедился, что он работает как можно быстрее. Но все равно это было медленно ... пока не вошел какой-то парень и не сказал, что есть какая-то инструкция BIOS / VGA или что-то, что может мгновенно очистить экран.

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