別の言語から関数を呼び出した場合、言語バインディングが必要なコンパイル済みライブラリに言語が残すマークは何ですか?
オブジェクト コードは「言語フリー」に見えます。
Linux環境でcでOpenGLを学習している間、私は言語バインディングにまたがっています。
あなたは若いか、10年以上プログラミングをしていないかのどちらかだと思います。
オブジェクト コードは言語に依存しないように見えるはずですが、それは歴史のせいではありません。1970 年代から 1980 年代にかけて、Intel 80x86 および Motorola 680x0 CPU では、関数呼び出しの引数がスタックで渡されました。「Pascal」規約では、引数の数が固定され、呼び出された関数コードが戻る前にそれらをスタックから削除していました。'C' 規約では、引数の数は変数 (printf など) であったため、呼び出しコードは、関数が返されたときに引数を削除する必要がありました。これにより、関数呼び出しごとに 2 バイト余分にコストがかかります。これは、今日では何もありませんが、PC に 128K 程度の RAM しか搭載されていなかった当時は重要でした。そのため、Microsoft は C で記述されていたにもかかわらず、Windows API に Pascal 呼び出し規約を使用することを選択しました。オブジェクト コードが誤って C 規約で Windows 関数を呼び出した場合、kaboom.
1990 年代以降、オペレーティング システムの作成者はこれがばかげていることに気づき、すべての人に標準の呼び出し規約を課し始めました。C の規則は両方のケースを処理できるため、あらゆる場所で使用されました。MacOS X、64 ビット Windows、および ARM への移行に伴い。ついに言語フリーのオブジェクトコードを手に入れました。
現在、OpenGL は C および Fortran から使用できるように設計されています。(1990 年代にはまだ科学計算と視覚化のための重要な言語でした。) どちらの言語にも、整数、浮動小数点数、およびさまざまなサイズの int/float の配列があります。C には構造体がありますが、Fortran にはありません。これが、OpenGL API が構造体を使用しない主な理由だと思います。C と Fortran の間では、2 次元以上の配列のメモリ レイアウトにも違いがあります。ここでも、OpenGL API は 2 次元配列を指定せず、1 次元のみを指定することに注意してください。
AC API は、ほとんどの言語で機能します。これは、C がほとんどすべての CPU とオペレーティング システムで動作する「ポータブル アセンブラ」であるためです。また、一般的に使用されている他のほとんどのプログラミング言語は、C のスーパーセット (C++、Objective-C) であるか、C 自体で実装されている (Python、Perl、Ruby) ため、OpenGL C API を合理的に簡単に呼び出すことができます。
Java と C# は、いわば独自のオブジェクト コードを定義し、メモリ アクセスがより厳密に制御されているため、より多くの問題を抱えています。C/OpenGL の「ここはメモリ ブロックへのポインタです。好きなように操作してください」という概念は、JVM/CLR のセキュリティ モデルを壊します。そのため、配列を渡すだけでなく、Java NIOByteBuffer を使用する必要があります。
その多くは、言語バインディング デザイナーのスキルにも依存します。一例として、Mike Fletcher による Python-OpenGL は非常に優れたバインディングです。すべての関数と定数はまったく同じ名前であるため、多くのコードを C からコピーして Python に貼り付けることができます。Python には C スタイルの配列が直接ありませんが、言語バインディングは、"配列" として渡された Python シーケンス/タプルを基になる C 形式にサイレントに変換します。これは Python プログラマーにとって自然に感じられるものであり、OpenGL の全機能を公開しています。
悪い例として、JOGL はお尻の痛みです。Java 配列から C への自動変換はないため、自分で NIOByteBuffers をいじる必要があります。glBegin..glEnd ブロックを使用する方が実際には簡単であるほど面倒です。また、追加の配列オフセット引数が多くの OpenGL 関数に追加されたため、コードが C/C++ と同じように見えなくなり、関数呼び出しの最後に ,0 を貼り付けて多くの時間を無駄にしています。前述のように、これの一部は JVM によるものですが、その多くは、OpenGL 自体を実際にあまり作成したことがない (と思われる) 誰かによる単なる悪い設計です。
あいまいな質問に対する長くとりとめのない答え。
C と C++ の無数の呼び出し規約について考えてみてください。stdcall
重大な事故を防ぐために、コンパイラは呼び出し規則に基づいて関数名をマングルし、規則を使用して誤って関数を呼び出さないようにしますfastcall
。各言語には、言語に依存しない API が負担する必要のない、このような余分な詳細の独自のセットがあります。言語バインディングは、言語固有のものを標準化された API から分離するアダプター/ブリッジとして機能し、必要に応じてギャップを埋めます。
OpenGL API は通常、単一の言語 (C) で実装され、他の言語で記述されたプログラムは、言語バインディングを通じてシステムの実装とインターフェイスします。OpenGL は GLSL に null で終わる ASCII 文字列を使用し、ポインターを使用する多数の関数を備えています。これは、C で実装するように設計された API にとって完全に理にかなっています。Java では、文字列は null で終了せず、UTF-16 でエンコードされています。 ; ブリッジが必要な理由がわかります。Java GL バインディングは、文字列変換を処理し、alterglVertexPointer (...)
のような関数を使用して、連続するメモリ ブロックを「指す」という Java の条件に適合させます。