私はそれが可能であり、Windows APIのオープンソースバージョンをどのように書くのかについて疑問に思っています。
これは、C++アプリケーションで_#include <Windows.h>
_と言っていることを意味します。次に、::CreateProcess(...)
を呼び出します。その関数が何をするのかを知っていて、関数の署名が何であるかを知っていて、クロスプラットフォームのライブラリに自分で実装した場合、メインのWindowsライブラリをカスタムライブラリと交換して、別のOSで実行できますか?クロスプラットフォームライブラリにWindowsAPIを完全に実装した場合、Windows以外のプラットフォームで任意のVisual C++アプリケーションを実行できるという考えです。
誰かがWindowsAPIのオープンソースバージョンを書くことができますか?
はい、でもあなたは間違った質問をしています!
さて、そのティーザーの後;-)少し後退しましょう。
「誰かがXを書けるか」という質問に対する答えは、ほとんどの場合「はい」です。 「いいえ」でない限り。まあ、わかりました、それはひどく役に立ちません。明らかに、はい/いいえの質問に対する答えは、はいまたはいいえのいずれかです。
つまり、計算可能性にはいくつかの基本的な制限があります。最も有名なのはアラン・チューリングの停止問題です。自然数にはかなり単純な数学関数があります。 かなり加算ほど単純ではありませんが、かなり近いです。H(p、i)= 1 IFFプログラムpは入力iで停止し、それ以外の場合は0です。それは明らかに関数であり、明らかに自然数の範囲内にあります(どのような種類の入力もプログラム自体も自然数としてエンコードできることがわかっています。実際、現代のコンピューターは、実際に数値だけを使用してエンコードできることを示しています0および1)。しかし、アラン・チューリングが証明したように、この関数を計算するプログラムを書くことは不可能です。ライスの定理も同様です。他にも同様の結果がたくさんありますが、そのほとんどは、デッドコード除去(不可能、HPと同等)、クラス階層分析(HP)、エスケープ分析(HP)などのいずれかで削減または証明できます。
基本的に、プログラムを実行せずにプログラムについて重要なことを理解するためにプログラムを作成したいときはいつでも、それは不可能です。
したがって、これら種類の質問の場合、「誰かがXを書くことができる」という答えは常にいいえです。これは数学的な「いいえ」であり、「理論的にはできません」それが、それはあまりにも難しい/高価/遅いなどです。」それは単純に不可能です。限目。
その他すべての質問の場合、「誰かがXを書けるか」の答えは常に「はい」です。特に、この場合、あなたはnotプログラムを静的に分析しようとしているので、上記で述べたことの後、答えは「はい、できます」になります。
構築したいものは、抽象化レイヤー、エミュレーター、仮想マシン(「Java」の意味ではなく、理論的な意味で)と呼ぶことができます。 、インタプリタ、アダプタ、翻訳層、互換性層、またはそのようなもの(見方によって異なります)それと、実際にそれを実装する方法)、そしてそれを行うことは完全に可能です。
実際、これらすべては再びアランチューリング、アロンゾチャーチ、そしてコンピューティングの始まりにまでさかのぼります。 Alan Turingは、niversal Turing Machinesが存在することを証明しました。これは、any Turing Machineの説明を入力として受け取り、そのTuringMachineの計算を実行できます。これは本質的に、最初の実際のインタプリタとコンピュータが構築される前の、インタプリタの最初のインスタンスとストアドプログラムコンピュータの最初のインスタンスです。その後、チューリングの万能チューリング機械と教会のλ計算のどちらがより強力であるか、より強力でないか、または同等に強力であるかという疑問が生じたとき、万能チューリング機械は、単にλ計算をエミュレートすることによって、λ計算で可能なことをすべて計算できることが証明されました。 λ-calculusは、UTMをエミュレートすることにより、UTMが実行できるすべてのものを計算できます。 μ再帰関数、SKコンビネーター計算など、他の計算モデルについても同じことが証明されました。
実際、これまでに見つかったevery計算モデル(有限状態マシンなど、意図的に制限されたモデルを無視)の場合、他のすべてのモデルをエミュレートでき、他のすべてのモデルでエミュレートできることがわかりました。モデル。これは有名なチャーチチューリングテーゼにつながりました:計算のすべてのモデルは等しく強力です。これには、量子コンピューターのような物理的に複雑なもの、さらには物理的に不可能非決定性チューリングマシンのようなものも含まれます。
それで、これはすべてあなたの質問と何の関係がありますか?まあ、このように考えてください。Win32APIは、一種の抽象マシンのようなものです(ここでも、「ガベージコレクションを使用したバイトコードインタープリタループ」ではなく、より抽象的な意味で)。 POSIXAPIもそのようなマシンです。そして、歴史の中で何度も見てきたように、あるマシンが別のマシンをエミュレートすることができます。
つまり、あなたの質問に対する答えは「はい、それは可能です」です。
実際、考えてみれば、すでにareさまざまなプラットフォームでのWin32 APIのさまざまな実装があります:16ビットDOS(Windows 3.x)、32ビットWindows(Windows 9x/ME) )、およびWindowsNT。 WoW64は4番目の実装であると言えます。実際、AMD64のWoW64はIA-64のWoW64とは非常に異なるため、WoW64はtwo実装であると主張できます。
しかし、最初に言ったように:それは間違った質問です!
あなたが本当に尋ねる必要がある質問は、「どれくらい難しいですか?」です。つまり、Wordの複雑さ理論的な意味と、それに投入する必要のある作業量、つまり2つのAPI間のマッピングがどれほど複雑かということの両方を意味します。
[興味深いことに、これは私が前述した「不可能」なプログラムにも逆に適用されます。明らかに、コンパイラーdoは、デッドコード分析やエスケープ分析など、プログラムに対してあらゆる種類の静的分析を実行します。 不可能から常にこれを行うだけです。 IOW、何かがデッドコードであるかどうかを明確に判断できるプログラムは無限にありますが、アルゴリズム的にどちらか一方を決定できないプログラムも無限にあります。そのため、そのコードを含める必要があります。プログラムが壊れるかもしれません。]
もう一度、上記の例を見てみましょう。はい、ユニバーサルチューリングマシンは非決定性チューリングマシンをエミュレートできますが、エミュレーションオーバーヘッドは指数関数的です(!!!)。そして、量子コンピュータは古典的なコンピュータより多くのものを計算することはできませんが、それはsomeものかなりより速く計算できます。
「マッピングの複雑さ」について、例としてC++とCを取り上げましょう。CはC++で可能なことなら何でも計算でき、C++はCの構造体にマッピングできます。ただし、そのマッピングは非常に直接的な場合があります(オーバーレイされていないC++関数はC関数として直接エンコードされる)、少し複雑な場合があり(オーバーレイされたC++関数は複数の異なる名前のC関数、別名名前マングリングとしてエンコードする必要があります)、マッピングが完全に自明でない場合もあります(オブジェクトのマッピングなど)。 、クラス、仮想メンバー関数、およびC構造体、vtable、ディスパッチ関数への継承)。
つまり、たとえば、Wineの問題:彼らは強調してnotエミュレータになりたいと思っています(名前にさえWine is not(an)Emulator)、彼らはむしろ、かなり単純な1:1API変換レイヤーを提供したいと考えています。そして、結局のところ、これはAPIの大部分で可能ですが、POSIXに簡単にマッピングできないAPIの一部では不可能です。 notはマッピングできないことを意味しますall、それは、Wineチームが設定した設計上の制約内で、財務、リソース、および人員だけでなく、私たちが「現実世界」と呼ぶこの厄介なものによって彼らに課せられる制約は、それを行う簡単な方法はありません。
別の方法でやりたい場合、つまり、より複雑な翻訳を許可し、弾丸を噛んでエミュレーションも行う場合は、Wineよりもはるか進んでください。たとえば、Monoチームは、いくつかの.NET APIを移植可能な方法で実装しましたにもかかわらず実際にはWin32とかなり緊密に結合されているという事実。 OTOH、彼らはnot他のいくつかのAPIを実装することを選択しました理由彼らの密結合(WinFormsなど)の。
この問題に通常取り組む方法は、両端からです。翻訳しやすいものを翻訳し、そうでないものを書き直します。 WineをターゲットにしてアプリケーションをLinuxに「移植」し、同時にWineの開発に参加し、より多くの機能を翻訳するためのパッチを提供し、同時にそれができない機能を使用するアプリケーションの部分を書き直している企業があります。簡単に翻訳できます。
だから、もう一度あなたの質問に答えるには:
誰かがWindowsAPIのオープンソースバージョンを書くことができますか?
はい、しかし、あなたがそれを作るつもりであるより完全で忠実であるならば、それはより遅くなるか、より複雑になるでしょう。特に、Win32とはトレードオフが異なる別の高レベルAPIにマップしようとした場合。 (そうしないと、Win32 APIをネイキッドCPUにのみマップするReactOSのようなものになります。これにより、複雑なマッピングを配置する必要がないため、高速になりますが、実装するコードははるかに多くなります。 simpleマッピングを使用することはできません。)
あんまり。ほとんどのAPIはそのように実装できますが、一部のAPIは、オペレーティングシステムで使用されるモデルを基本的に公開しています。たとえば、fork()
について考えてみます。これには、基本的にWindowsの実装はありません。
一般的なケースでは可能ですが、特定のAPIの場合、Linuxなどの基盤となるOSがその機能を提供していない可能性があります。