1

私はしばらくの間 Java で作業しており、コンパイルと実行に関して C++ がどのように機能するかを学びたいと思っています。

コンパイルされた C++ クラスを Java の .class ファイルに、またはその逆に変換する方法があるかどうか疑問に思っていました。私は、結果を確認するために直接実行できる Java コードと C++ コードの両方で使用できる単一の形式に興味があります。

4

4 に答える 4

5

あなたが野心的で頑固であれば、ほとんどすべてを行うことができますが、問題は通常、時間とコストと機能にあります..

本質的に、Java言語は C++ のサブセットです。匿名クラスの実装や外部クラスへの隠しポインタなど、「何かもっと」があると感じるかもしれない構文糖衣がいくつか追加されていますが、それは構文の薄い層に過ぎず、コードがコンパイルされると無関係になります。

コンパイル後、C++ コードはマシン コードで表されます。もちろん、Java のバイトコードはマシン コードに変換可能です。単純に、JVM がそれを実行し、ジッターがそのバイトコードをその場でマシン コードに再コンパイルできるという事実によります。

したがって、大まかに言えば、コンパイルされているかどうかに関係なく、すべての Java コードは C++ に変換可能です。

ただし、C++ には、機械語コードにコンパイルでき、Java のバイトコードで表現できても、Java 言語では表現できないコード構造がいくつかありますたくさんあります: パラメータを参照として渡すような簡単なものから、ポインター (TheList->) 算術演算のようなより複雑なものまで、多重継承やカスタム メモリ管理 (つまり、オーバーロードされた演算子) のように変換するのが本当に面倒なものまであります。 new と delete)、またはユニオンのようないくつかの邪悪なタイプ。

したがって、明らかに、C++ コードは Java に変換できません。明らかに、C++ コンパイラは製品を徹底的に最適化することが多いため、C++ でコンパイルされたコードはさらに翻訳可能ではありません。

ただし、C++ 言語を制限し、翻訳が困難な構造 (「TheList」を参照) を使用しないように制限すると、C++ コードを翻訳可能にすることができます。繰り返しますが、バイナリではなくコードです。

これだけではありません。「翻訳可能性」は 1 つのことですが、もう 1 つは、実行されるかどうかです。実行時の最も顕著な違いは GarbageCollector です。いくつかの Java コードを実際に C++ に変換し、それを C++ アプリケーションと並べたとしましょう。Java/C++ コードが実行され、いくつかのオブジェクトが作成されます。誰がそれらを片付けますか?通常、C++ には GC はありません。したがって、Java コードがリークします。または、Java/C++ コードにある種の GC を提供/実装する必要があります。きれいではありません。もちろん、オブジェクトを作成しないように Java コードを制限することもできます。

誤解しないでください: ポインター演算などの翻訳が難しいものでさえ翻訳可能です:それらを「第 2 プラットフォームの適切なもの」に置き換える大量のヘルパー/ワイヤーアップ コードを生成できます。ただし、途方もなく複雑で遅くなります。正気な人が試みることはないと思います。

したがって、利用できるように見える唯一のものは、非常に限定された C++ コード <-> やや限定された Java コードです。質問をこれに切り詰めると、はい、それは翻訳可能なはずです。しかし..

コードを翻訳するとはどういう意味ですか? どうやってやったの?ソース コードを読み取り、処理し、分析してから、別の言語で何らかの方法で別のコードを生成する必要があります。まぁ、いいよ。コードの作成は単純です。それは単なるテキストです。しかし、コードを分析しようとしたことがありますか? 簡単に言えば、Java コードの読み取り/解析は、少なくとも 1桁は簡単です。その読み取り/解析 C++ コード。Java は、比較的単純なアルゴリズムで簡単に解析できるように設計されていました。最適化の試みをやめれば、Java パーサー/コンパイラーの作成は比較的簡単になります。一方、C++ はそうではありませんでした。Java と同様に、C++ を適切に解析するには、カスタム C++ コンパイラだけでなく、プリプロセッサも効果的に作成する必要があります。ある程度、リンカーの一部を実装する必要がある場合もあります。さらに悪いことに、C++ は古い言語から進化したものであり、構文を正確に処理するのを非常に困難にする一生に一度しか使用されない機能が文字通り詰め込まれています (つまり、代替トークン セットを使用したことがありますか)。? ..そしてこれは始まりにすぎません:))。ただし、怖がりすぎないでください。私はあなたが触れようとしているものをあなたに感じてもらいたいだけです。おそらく書く必要はないでしょう。このようなツールは、Java (実際には非常に多く) と C++ (少数です。合理的なものは完全に無料ではないに違いありません.. または、おそらく GCC ツールセットを使用することもできます..) の両方に既にツールが存在します。それらは、ソースコードの機械処理可能な表現を生成します。本当に翻訳作業を行いたい場合は、そこから始めることをお勧めします。

もちろん、私の知識は数年ずれている可能性があります。おそらく、誰かがすでに実用的な翻訳者を書いているかもしれません。ぜひ見てみたいです!

そうでなければ、もったいないと思います。Java のランタイムを C++ アプリに埋め込んでみるか、JNI を介して Java から C++ DLL に話しかけてください。それははるかに簡単です!

于 2013-01-17T08:58:28.747 に答える
3

コンパイルされたC++コードはOSによってロードされます。つまり、C++リンカはOSに依存する実行可能モジュールを生成します。一方、Java.classはJVMによってロードされます。JVMはJavaバイトコードを実行します。

Javaバイトコードローダー/ランナーを作成したい場合は、JVMソースコードから始めることができます。
=>リンク

コンパイルされたC++コードをJava環境でロード/実行する場合は、以下が必要です。
(32ビットWindowsプラットフォームを想定)

。PEパーサー/ローダー=>リンク
。X86 CPU命令パーサー(?)=>リンク
。X86命令からJavaバイトコードトランスレータへ

要するに、それはほとんど不可能です。

単純なC/C ++とJavaの相互運用の場合、JNIが行います。リンク

于 2013-01-17T08:43:33.887 に答える
0

コンパイル済みの C++ コードを JVM バイトコードに変換するのは簡単なことではありません。コンパイル済みの C++ コードを複数のプラットフォームから使用できるようにしたい場合は特にそうです。

代わりに、 clang用の JVM バックエンドを作成する方がおそらく簡単です。ここでの欠点は、この機能が必要な場合はコンパイラを使用する必要があることです。

つまり、Java 仮想マシンを対象とするコードを作成する場合は、そのために既に作成されている言語とコンパイラを使用します。ジャバのように...

于 2013-01-17T08:48:00.153 に答える
0

JNIは便利だと思います:

「Java Native Interface (JNI) は、Java 仮想マシン (JVM) で実行されている Java コードが、ネイティブ アプリケーション (ハードウェアおよびオペレーティング システム プラットフォームに固有のプログラム) および記述されたライブラリを呼び出したり、呼び出したりできるようにするプログラミング フレームワークです。 C、C++、アセンブリなどの他の言語で。」

ここで は、Java Native Interface を使用する簡単な例 (C 関数を呼び出す Java アプリケーションを作成する) をプログラミングするためのヒントを紹介します。

于 2013-01-17T08:37:48.400 に答える