問題タブ [binary-compatibility]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - クラスのプライベート データ メンバーの順序を変更すると ABI が壊れますか
仮想および非仮想メンバー関数によってアクセスされる、多数のプライベート データ メンバー (一部は静的) を持つクラスがあります。インライン関数もフレンド クラスもありません。
この場合、プライベート データ メンバーの順序を変更すると ABI が壊れますか?
編集
タイプは変更されず、メンバーの順序のみが変更されます。ビット フラグも使用されません。コードは共有ライブラリとして使用され、このコードへの静的リンクはありません。私は Linux を使用しており、コンパイラは gcc-3.4.3 と gcc-4.1 です。
dependencies - さまざまなバージョンの glib ヘッダーを含める
ac と bc の 2 つのソース ファイルがある場合: ac は glib-2.6.6 の glib.h をインクルードし、bc は glib-2.12 の glib.h をインクルードします。
次に、それらをコンパイルしてリンクし、ターゲット プログラムを生成します。ac が v2.6 以降に導入された新しい機能を使用していないと仮定すると、異なるバージョンのヘッダーを含めると問題が発生しますか? もしそうなら、そのような問題はいつ起こりますか?
java - Javaバイナリ互換性-invokevirtualセマンティクスを使用した共変リターンタイプの提案されたソリューションに関するRFC
APIを進化させようとしています。この進化の一環として、高度なクライアントが新しい機能にアクセスできるようにするには、メソッドの戻り型をサブクラス(特殊化)に変更する必要があります。例(醜いものは無視してください:
私は今、次のようにExtendedEntity、Intf2、およびMainを使用したいと考えています。
ただし、メソッドの戻り型はそのシグネチャの一部であるため、以前のバージョンのコードですでにコンパイルされているクライアントは、リンケージエラーを示します(メソッドがiircで見つかりません)。
私がやりたいのは、別の戻りタイプを持つメソッドをMainに追加することです。2つのメソッド(1つはスーパータイプを返し、もう1つはサブタイプを返す)は、同じ実装メソッド(サブタイプを返す)にマップする必要があります。注-私が理解している限り、これはJVMで許可されていますが、Java仕様では許可されていません。
私の解決策は、必要なインターフェースを追加するためにJavaクラスシステムを悪用しているようです(私はそれについて他の言葉はありません)。
これで、古いクライアントは正しいメソッドをinvokevirtualルックアップに返します(正しいリターンタイプのメソッドがタイプ階層に存在するため)。実際に機能する実装は、サブタイプIntf2を返す実装になります。
これはうまくいくようです。私が考案できたすべてのテストで(リフレクションを除いて-しかし、私はそのビットについては気にしません)、それは機能しました。
それは常に機能しますか?私の推論(invokevirtualについて)は正しいですか?
そして、別の関連する質問-「実際の」バイナリ互換性をチェックするためのツールはありますか?私が見つけた唯一のものは、それ自体で各メソッドを調べますが、タイプ階層を考慮していません。
ありがとう、
蘭。
編集-私が試したツールで「あまり良くない」ことがわかりました(タイプ階層を考慮しないでください):
- Clirr0.6。
- IntelliJ「APIComparator」プラグイン。
Edit2-もちろん、私のクライアントは私のインターフェースへの実装クラスを作成することを禁じられています(サービスを考えてください)。ただし、例を完全なものにしたい場合は、インターフェイスではなく抽象クラス(Main用)を検討してください。
linux - 最高のバイナリ互換性を得るには、どのLinuxディストリビューションにリンクする必要がありますか?
共有ライブラリに対して可能な限り多くのディストリビューションで機能するバイナリをリンクする場合、どのLinuxディストリビューションが最適であるか(つまり、依存関係が最も少ないか)疑問に思っています。
私はUbuntuでそれを行いましたが、依存関係のリストはひどいものです。SDLはPulseAudioなどを紹介します。私の次の推測は、Debian lennyを使用することです-あなたの意見では、そのための最良のディストリビューションは何ですか?
java - 流暢さを促進するために引数を返すように void メソッドを改良する: 破壊的な変更?
「API の設計はセックスのようなものです。1 つの間違いを犯すと、残りの人生をサポートすることができます」 ( Twitter の Josh Bloch )
Java ライブラリには多くの設計ミスがあります。Stack extends Vector
(ディスカッション)、破損を引き起こさずにそれを修正することはできません。廃止しようとすることはできますがInteger.getInteger
(議論)、おそらく永遠に残るでしょう。
それにもかかわらず、特定の種類のレトロフィットは、破損することなく行うことができます。
効果的な Java 2nd Edition、項目 18: 抽象クラスよりもインターフェイスを優先する: 既存のクラスは、新しいインターフェイスを実装するために簡単に改造できます。
例: String implements CharSequence
、Vector implements List
など
有効な Java 2nd Edition、項目 42: varargs を慎重に使用する: 既存のクライアントに影響を与えずに、最終パラメーターとして配列を受け取る既存のメソッドを改造して、代わりに varags を使用できます。
(悪名高い) 有名な例はArrays.asList
、混乱 (議論) を引き起こしましたが、破損は引き起こしませんでした。
この質問は、別の種類の改造に関するものです。
void
既存のコードを壊さずに何かを返すようにメソッドを改良できますか?
私の最初の予感はイエスです。
- 戻り値の型は、コンパイル時に選択されるメソッドには影響しません
- 参照: JLS 15.12.2.11 - 戻り型は考慮されない
- したがって、戻り値の型を変更しても、コンパイラによって選択されるメソッドは変更されません。
- を改造し
void
て何かを返すことは合法です (ただし、その逆はできません!)
- リフレクションを使っても
Class.getMethod
返り値の型が区別されないなど
ただし、Java/API 設計の経験が豊富な他の人による、より徹底的な分析を聞きたいと思っています。
付録: 動機
タイトルで示唆されているように、1 つの動機は流暢なインターフェイススタイルのプログラミングを容易にすることです。
シャッフルされた名前のリストを出力するこの単純なスニペットを考えてみましょう:
入力リストを返すCollections.shuffle(List)
ように宣言されていた場合、次のように記述できます。
の代わりに、などCollections
の入力リストを返すと、はるかに快適に使用できるメソッドが他にもあります。実際、とreturnを持つことは特に不幸です。このように:void
reverse(List)
sort(List)
Collections.sort
Arrays.sort
void
もちろん、流暢さを妨げているこのvoid
戻り値の型は、これらのユーティリティ メソッドだけに限定されているわけではありません。メソッドは、流暢さを促進するために(alaおよび) をjava.util.BitSet
返すように作成することもできます。this
StringBuffer
StringBuilder
残念ながら、StringBuilder
/とは異なりStringBuffer
、すべてのBitSet
ミューテーターは を返しvoid
ます。
関連トピック
xcode - GCC 4.0、4.2、およびLLVMABIの互換性
Xcodeでサポートされている3つの主要なコンパイラフレーバー(gcc 4.0、4.2、およびllvm)は、相互にバイナリ互換ですか?マルチライブラリプロジェクトを最新のXcodeツールで高速化する場合、どのような落とし穴とコーナーケースに注意する必要がありますか?
.net - .NET ライブラリでバイナリ互換性を達成することは可能ですか?
COM で表示できる .NET ライブラリがあり、vb6 アプリケーションから呼び出されます。
いくつかのメソッドを追加して新しいバージョンをリリースする場合 (ただし、既存のメソッドのシグネチャを消去または変更しないでください)、運用マシンにインストールするだけで機能するようにしたいと考えています。ただし、そのようなアプローチは機能しないようです。vb6 アプリケーションを再コンパイルする必要があります。
これを達成する方法はありますか?
gcc - 古いシステムで動作する新しい gcc バイナリ
gcc 4.4.0 でコンパイルされたバイナリがあり、gcc 4.4.0 がない古いシステムで実行しようとしています。うまくいきません。エラーは、シンボルが見つからないということではなく、正しく実行されずにハングするだけです。システム間の違いは、CentOS 5.5 と 5.2、および gcc 4.4.0 と 3.4.6 です。
gcc 4.4.0 をインストールせずにそのシステムで実行するにはどうすればよいですか? それに置くことができるランタイムライブラリはありますか? 依存関係を単にコピーしてライブラリ パスを設定するだけでは機能しないようです。
バイナリには gcc 4.4.0 の機能が必要です。
com - VB6IDEがロードされたプロジェクトのDLLをロックしています
私はレガシーVB6コードを維持する責任があり、プロジェクトのCOMDLLのロックに関して厄介な問題に遭遇しました。(これをMyProjectおよびMyProject.dllと呼びます)
MyProjectをVB6IDEにロードすると、結果のバイナリ互換DLLMyProject.dllをコンパイルできます。次に、DLL(またはその他の問題)にフックする(クラシックASP)Webアプリケーションを実行できます。
そのため、COM DLLを再コンパイルしようとすると、「permissiondenied」エラーが発生します。次に、DLLのロックを解除するには、次の手順を実行する必要があります。
- 他のVB6IDEで開いている依存プロジェクトがないことを確認してください
- IISをリサイクルする
- ファイルが読み取り専用ではないことを確認します(ソース管理にチェックインした場合は、読み取り専用になることがあります)
- プロジェクトを閉じて、再度開きます。
多くの場合、これは問題を修正し、再コンパイルできるようにする最後のステップです。これは、VB6IDEが実際にロードされたプロジェクトのDLLをロックしていることを意味します。
私の同僚は、VB6プロジェクトがDLLのバイナリ互換性で動作する方法に関係していると説明しましたが、解決策を提案することはできませんでした。
他の場所での私の検索では、答えはほとんど得られませんでした。これに関連する検索クエリは、多くの無関係な回答を返す傾向があります(おそらく私は検索エンジンに間違ったことを尋ねています)。
Stackoverflowで見つけた最も近いものは、数年前のこの質問でしたが、実際には法案に適合していません。
誰かがこれを改善するかもしれない他の提案がありますか?
c - avr-gcc 3.4.0 と avr-gcc 4.3.x 間のバイナリ互換性
gcc3 でビルドされた可能性があるライブラリにリンクするアプリケーションを継承しました。または、imagecraft コンパイラを使用することもできます。その情報は天国のビットフィールドに消えてしまい、アプリをリンクするための libXXX.a ライブラリが残っています。libXXX.a を再コンパイルできません。これには、imagecraft や他の場所からの特定の不明なヘッダーが必要なためです。これは、ある時点で私の環境に遍在していた可能性がありますが、現在はどこにも見つかりません。
私の質問は、私のアプリを avr-gcc バージョン 3.4.0 (およびその「特別な」libXXX へのリンク) でコンパイルした結果、動作するバイナリ イメージが得られた場合、他のすべての部分をコンパイルできると期待するのは合理的ですか? avr-gcc 4 を使用した私のアプリ (このアクションには、いくつかの非常に優れた実証済みの利点があります)、libXXX とリンクしても、動作するプログラムを取得できますか?
基本的に、それはすべて次のように要約されます: avr-gcc バイナリは、「avr-gcc 3.something である可能性がある謎のコンパイラ X」と互換性がありますか?
正直なところ、アプリの残りの部分を avr-gcc4 でコンパイルしてライブラリにリンクし、結果が機能することを確認しましたが、どのような副作用や癖に気をつければよいでしょうか?