低レベルの WinAPI プログラミングを学ぶことはまだ意味がありますか?[閉まっている]

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

  •  08-06-2019
  •  | 
  •  

質問

C# マネージドのすべてを享受しているのに、Petzold のプログラミング Windows に戻って、純粋な WinAPI を使用してコードを生成しようとするのは理にかなっていますか?

そこから何が学べるでしょうか?あまりにも時代遅れすぎて役に立たないのではないでしょうか?

役に立ちましたか?

解決

この質問は宗教に近いものです:) しかし、とにかく私の考えを述べます。

Win32 API を学ぶことに価値があると感じています。すべてではないにしても、ほとんどの GUI ライブラリ (マネージドまたはアンマネージド) では、Win32 API が呼び出されます。最も完全なライブラリであっても API を 100% カバーしているわけではないため、直接 API 呼び出しまたは P/invoking によって埋める必要があるギャップが常に存在します。API 呼び出しのラッパー名の一部は、基になる API 呼び出しと似た名前を持っていますが、それらの名前は正確には自己文書化されたものではありません。したがって、基礎となる API とそこで使用される用語を理解することは、ラッパー API とその実際の動作を理解するのに役立ちます。

さらに、フレームワークによって使用される基盤となる API の性質を理解していれば、特定のシナリオでどのライブラリ機能を使用する必要があるかについて、より適切な選択ができるようになります。

乾杯!

他のヒント

私は Win32 API を学ぶまで何年も標準 C/C++ を使い続けてきましたが、率直に言って、「Win32 API の学習」の部分は私の人生で最高の技術経験ではありませんでした。

一方で、Win32 API は非常に優れています。これは C 標準 API の拡張機能のようなものです (誰が必要とするでしょう) fopen いつ食べられるか CreateFile. 。ただし、UNIX/Linux/WhateverOS には同じギズモ機能があると思います。とにかく、Unix/Linux では、「すべてがファイルである」ということになります。Windows では、「すべては...窓」(冗談じゃないよ!見る CreateWindow!).

一方、これはレガシー API です。あなたは生のC、そして生のCの狂気を扱うことになるでしょう。

  • 自分の構造にそれ自身のサイズを伝えて通過するのと同じです。 void * 何らかの Win32 関数へのポインタ。
  • メッセージのやり取りも非常にわかりにくい場合があります。C++ オブジェクトと Win32 ウィンドウを混合すると、非常に興味深い例が得られます。 鶏か卵か 問題 (ある種の文章を書くときの面白い瞬間) delete this ; クラスメソッド内)。
  • オブジェクトの継承に慣れているときに WinProc をサブクラス化する必要があるのは、頭を痛める作業であり、最適とは言えません。
  • そしてもちろん、「」という喜びもあります。なぜこの水圧破砕の世界で彼らはこのようなことをしたのでしょうか??「何度も頭でキーボードを打ちすぎて、額にキーが刻まれた状態で家に帰ってくる瞬間。それは単に誰かが、「ウィンドウ」の色の変更を可能にする API を書くほうが論理的だと考えたからであり、「ウィンドウ」の色の変更を可能にするのではなく、プロパティの 1 つを変更しますが、そのプロパティを親ウィンドウに要求します。

最後のハンドでは (三つの手?)、レガシー API を使用している人の中には、自分自身もレガシー コード スタイルを使用していることを考慮してください。「」を聞いた瞬間、const ダミー用です" または "名前空間は実行速度を低下させるため使用しません。"、あるいはさらに良い"ねえ、誰が C++ を必要とするでしょうか?私は自分のブランドのオブジェクト指向 C でコーディングしています。「(冗談じゃないよ…)プロフェッショナルな環境で、その結果はかなりの光景でした...)、あなたは、非難されるだけの恐怖を目の前で感じるでしょう。 ギロチン.

それで...全体として、それは 面白い 経験。

編集

この投稿を読み直してみると、過度に否定的であると思われる可能性があることがわかりました。そうではない。

物事が内部でどのように機能するかを知ることは、時には興味深い (イライラするだけでなく) こともあります。膨大な (不可能?) 制約にもかかわらず、Win32 API チームは、「古い Win16 プログラム」から「最後の Win64 オーバーザトップ アプリケーション」まで、すべてが確実に連携できるように素晴らしい仕事をしたことがわかります。過去、現在、そして未来。

質問は:本当にそうしたいですか?

なぜなら、他のより高度な API やオブジェクト指向の API で実行できる (そしてより適切に実行できる) ことを行うために何週間も費やすと、かなりモチベーションが下がってしまう可能性があるからです (実際の経験:Win API の場合は 3 週間、他の 3 つの言語および/またはライブラリの場合は 4 時間です)。

とにかく、Raymond Chen のブログは、Win API とその長年にわたる進化の両方に関する内部関係者の視点から非常に興味深いものであることがわかります。

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

絶対に。低レベル言語を誰も知らない場合、誰が高レベル言語を更新して作成するのでしょうか?また、低レベルの内容を理解すると、より高レベルの言語でより効率的なコードを作成し、より効率的にデバッグできるようになります。

ネイティブ API は、「実際の」オペレーティング システム API です。.NET ライブラリは (いくつかの例外を除いて) それらを包む派手なラッパーにすぎません。そうですね、.NET の複雑さを理解できる人なら誰でも、仲介者の恩恵を受けることなく API との通信などの比較的日常的なことを理解できると思います。

マネージ コードから DLL インジェクションを実行してみてください。それはできません。このため、ウィンドウの微調整、実際のサブクラス化、その他多数のことのためにネイティブ コードを作成する必要があります。

あ、はい:両方を知っておく必要があります(しなければなりません)。

編集:P/Invoke を使用する予定がある場合でも。

Windows を対象としたアプリを構築していると仮定すると、次のようになります。

  • システムの下位レベル、つまりシステムがどのように機能するか、コードがそれらとどのように対話するか (間接的であっても)、上位レベルの抽象化では利用できない追加オプションがある場所などを理解することは確かに有益です。
  • コードが効率的、高パフォーマンス、または要件に対して十分に正確ではない場合があります。
  • しかし、私たちのような人 (「アンマネージ コーディング」を学んだことがない人) が、Win32 を「学ばなくても」やろうとしているプログラミングをやり遂げられるようになるケースがますます増えています。
  • さらに、実用的なサンプル、コードの断片、さらには完全に機能するソース コードを提供するサイトがたくさんあり、それらを「活用」(借用、盗用 - ただし、再利用ライセンスや著作権を順守していることを確認してください!)できます。 .NET Framework クラス ライブラリ (またはダウンロードまたはライセンスを取得できるライブラリ) によって処理されないギャップ。
  • Win32 をいじることなく必要な偉業を成し遂げることができ、整形式で読みやすいマネージ コードをうまく開発できているのであれば、手薄に勉強するよりも .NET をマスターする方が良い選択だと思います。 2 つのまったく異なる環境にわたって。
  • Framework クラス ライブラリで十分にカバーされていない Windows の機能を頻繁に利用する必要がある場合は、ぜひ必要なスキルを習得してください。
  • 私は個人的に、コーディングの「他の領域」について心配することにあまりにも多くの時間を費やしてきました。 想定 「良い番組」を作るには理解する必要があるが、世の中にはみんなのニーズや欲望が自分のものと同じだと考えるマゾヒストがたくさんいる。ミザリーは仲間が大好きです。:)

「Web 2.0」の世界向けのアプリを構築している、または *NIX および MacOS ユーザーにとっても同様に便利/有益であると仮定すると、次のようになります。

  • できるだけ多くのクロスプラットフォーム環境を対象とする言語とコンパイラを使用してください。
  • Visual Studio の純粋な .NET は明らかに Win32 よりも優れていますが、おそらく Sharp Develop IDE を使用して MONO ライブラリに対して開発することは、おそらくさらに優れたアプローチです。
  • Java の学習に時間を費やすこともでき、そのスキルは C# プログラミングに非常にうまく応用できます (さらに、理論上、Java コードは一致する JRE を備えた任意のプラットフォームで実行できます)。Java は「一度書けば、どこでもデバッグできる」ようなものだと聞いたことがありますが、それはおそらく C# と同じくらい (あるいはそれ以上に) 真実です。

類推:車の製作 (プログラミング) を生業としている場合、エンジン (Win32) がどのように動作するかを知ることは非常に重要です。

簡単な答えは「はい」です。

これは、次のような質問に対する答えです。 「高レベル言語/API Y がある場合でも、低レベル言語/API X を学習するのは意味がありますか?」

はい

Windows PC (またはその他の OS) を起動して、SO でこの質問をすることができます。これは、Microsoft の数人が、OS をロードする 16 ビットのアセンブリ コードを作成したためです。

ブラウザが動作するのは、誰かがブラウザのすべてのリクエストに対応する OS カーネルを C で記述したためです。

それはスクリプト言語にまで及びます。

規模の大小に関わらず、あらゆる抽象レベルで何かを書く市場と機会は常に存在します。ただそれが好きで、適切な仕事に就く必要があります。

どの抽象化レベルでも無関係な API/言語はありません 同じレベルでより優れた選手がいない限り.

別の見方:マイケル・アブラッシュ氏の本の 1 つからの良い例:C プログラマーには、画面をクリアする関数を作成するというタスクが与えられました。C はアセンブリなどよりも優れた (より高いレベルの) 抽象化であったため、プログラマは C しか知らず、それをよく知っていました。彼は最善を尽くしました。カーソルを画面上の各場所に移動し、そこでキャラクターをクリアしました。彼はループを最適化し、可能な限り高速に実行できるようにしました。しかし、それでも遅かったです...誰かがやって来て、BIOS/VGA命令か、画面を瞬時に消去できる何かがあると言うまでは。

自分が何を歩いているのかを知ることは常に役立ちます。

はい、いくつかの理由があります:

1) .net は Win32 コードをラップします。.net は通常、コードを作成するのに優れたシステムですが、基礎となる Win32 レイヤー (おっと、今では 64 ビット コードもあるので WinAPI) についてある程度の知識があると、実際に何が起こっているのかについての知識が強化されます。

2) この経済では、仕事を探すときに他の人よりもいくつかの利点がある方が良いです。WinAPI の経験によっては、これが役立つ場合があります。

3) 一部のシステム機能は .net フレームワークではまだ利用できません。これらの機能にアクセスしたい場合は、p/invoke を使用する必要があります (「 http://www.pinvoke.net そこに助けが必要です)。少なくとも WinAPI の経験が少しあれば、p/invoke の開発作業がより効率的になります。

4) (追加) Win8 が登場してしばらく経ちましたが、 まだ WinAPI 上に構築されています。iOS、Android、OS/X、Linux はすべて存在しますが、WinAPI は今後も何年も存在し続けるでしょう。

新しいプログラミング言語またはテクノロジーを学習する理由は次の 3 つのうちいずれかです。
1.必要:Web アプリケーションを構築するプロジェクトを開始しようとしていますが、ASP.NET については何も知りません。
2.熱意:あなたは ASP.NET MVC にとても興奮しています。それを試してみてはどうでしょうか?
3.自由時間:しかし、とにかくそれを持っている人は誰ですか。

何か新しいことを学ぶ最大の理由は、それが必要だからです。.NET Framework では実行できないこと (パフォーマンスなど) を実行する必要がある場合は、WinAPI がソリューションになります。それまでは、.NET について学ぶことに専念します。

デスクトップ上のほとんどのニーズでは、Win32 について知る必要はありません。ただし、.NET には Win32 がたくさんありますが、それはアプリケーションの 1% 未満になる可能性のある高価なものに含まれています。

USB サポート、HID サポート、Windows Media Foundation はすぐに思いつきます。Win32 からのみ利用できるクールな Vista API が多数あります。

デスクトップ プログラミングを行っている場合は、Win32 API との相互運用方法を学習すると、非常に役立ちます。Win32 を呼び出す必要があるときに、何週間も頭を悩ませる必要がなくなるからです。

個人的には、Win32 API はあまり好きではありませんが、Visual Basic のような言語よりも GUI を使用して API を使用すると、より多くの制御と効率が得られるので、学ぶ価値はあります。ソフトウェアを書いて生計を立てるのであれば、 API を直接使用しない場合でも、API については知っておく必要があります。これは、C を学ぶのが良い理由と同様の理由です。たとえば、strcpy は整数をコピーするよりも時間がかかる、あるいは、値による配列ではなく配列へのポインタを関数パラメータとして使用する必要があるなどです。

C 言語または低レベル言語を学習すると、間違いなく役立ちます。ただし、アンマネージド WinAPI を使用することに明らかな利点はありません。

低レベルの Windows API コードを見ました...きれいじゃない...それを忘れることができればいいのですが。ハードウェア アーキテクチャとその仕組みをより深く理解するには、C のような低レベルを学ぶことが有益だと思います。古い W​​indows API を学習しています...このようなことは、高レベルの言語や API を構築するためにそれを学ぶ必要があるかもしれない Microsoft の人々に任せることができると思います...彼らがそれを作ったのだから、それで苦しんでもらいましょう ;-)

ただし、高水準言語では必要なことを実行できないと感じる状況に遭遇した場合 (ほとんどありません)、おそらくその世界に危険な飛び込みを開始してください。

はい。驚くべきソフトウェア効率を実現する uTorrent を見てみましょう。サイズが小さいの半分は、そのコアコンポーネントの多くがガルガチュイアンライブラリを使用しないように書き直されたという事実によるものです。

これらの多くは、これらのライブラリが下位レベルの API とどのように連携するかを理解しなければ実行できませんでした。

Windows API で何が利用できるのかを知ることが重要です。コードを作成する必要はないと思いますが、それがどのように機能するかを知っておく必要があります。.NET Framework には多くの機能が含まれていますが、Windows API 全体に相当するマネージ コードは提供されていません。場合によっては、金属に少し近づく必要があります。そこに何があるか、金属がどのように動作するかを知ることで、金属の使い方をより深く理解できるようになります。

これは、C のような低レベル言語 (あるいはアセンブラでも) を学ぶべきかという質問と同じです。

コーディングは確かに遅くなります (もちろん、結果ははるかに高速ですが)。しかし、その真の利点は、何が起こっているかについての他人のメタファーを理解するだけではなく、システム レベルに近いレベルで何が起こっているかについて洞察が得られることです。 。

また、物事がうまく機能しない場合や、十分な速度が得られない場合、または必要な粒度で機能しない場合の方が良い場合もあります。(そして、少なくともいくつかのサブクラス化とスーパークラス化を実行します。)

このように置きます。私は Win32 API でプログラミングするのが好きではありません。マネージ コードと比較すると、面倒になる可能性があります。でも、それを知ってよかったと思います。なぜなら、そうでなければ書けなかったプログラムを書けるようになるからです。私は他の人には書けないプログラムを書くことができます。さらに、マネージド コードが舞台裏で何を行っているかについて、より詳細な洞察が得られます。

Win32 API の学習から得られる価値は、(マシンの基本とボルトがどのように組み合わされているかを学習することで得られる一般的な洞察は別として) 何を達成しようとしているかによって異なります。Win32 API の多くは .NET ライブラリ クラスにうまくラップされていますが、すべてがラップされているわけではありません。たとえば、本格的なオーディオ プログラミングを行おうとしている場合、.NET クラスからは最も基本的な操作しか利用できないため、Win32 API のその部分は優れた研究対象となるでしょう。最後にチェックしたところ、マネージド DirectX DirectSound ライブラリさえもひどいものでした。


恥知らずな自己宣伝の危険を冒して……。

Win32 API が唯一の選択肢である状況に遭遇しました。リストボックス内の各項目に異なるツールチップを表示したいと考えています。やり方を書きました この質問.

非常に高級な言語であっても、依然として API を使用します。なぜ?API のすべての側面がさまざまなライブラリやフレームワークなどによって複製されているわけではありません。やろうとしていることを達成するために API が必要になる限り、API を学習する必要があります。(そしてもうだめです。)

API への直接アクセスが必要ないくつかの非常に特殊なケースを除けば、私は「ノー」と言います。

ネイティブ API 呼び出しを正しく実装する方法を学ぶにはかなりの時間と労力が必要ですが、戻り値にはそれだけの価値がありません。私はむしろ、あなたの生活を楽にし、プログラミングの苦痛を軽減する新しい注目のテクノロジーやフレームワークを学ぶことに時間を費やしたいと思っています。もう誰も実際に使用していない、何十年も前に廃止された COM ライブラリではありません (COM ユーザーには申し訳ありません)。

この見解を理由に私を石にしないでください。ここのエンジニアの多くは本当に好奇心旺盛で、物事がどのように機能するかを学ぶことに何も悪いことはありません。好奇心を持つことは良いことであり、理解に非常に役立ちます。しかし、管理的な観点からすると、OLE や COM の呼び出し方法よりも、Android アプリの開発方法の学習に 1 週​​間を費やしたいと考えています。

クロスプラットフォーム アプリケーションの開発を計画している場合、win32 を使用すると、アプリケーションは WINE を介して Linux 上で簡単に実行できます。これにより、メンテナンス性の高いアプリケーションが実現します。これは、win32 を学習する利点の 1 つです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top