27

これに遭遇するのは私だけではありません。

SDK で設定された 1 つのサードパーティおよび別の静的ライブラリとリンクする必要がある C++ アプリケーションがあります。SDK は、非常に苛立たしい理由で、同じサードパーティ ライブラリのサブセットを独自の (名前が変更された) ライブラリに再コンパイルしましたが、シンボル自体は同じ名前であり、名前空間内にカプセル化されていません。私のアプリケーション自体は、同じサードパーティ ライブラリに依存しています。

いくつかのオプションを検討しましたが、何かが欠けている可能性があり、新しい外観が私を助けてくれることを願っています. おそらく私は近くにいて、誰かがこれらのいずれかの次のステップを知っているでしょう. これまでに試したことと、各ソリューションの欠点を列挙します。

  1. 両方にリンクします。約 2500 行のシンボルの再定義/サイズ変更の警告とエラーが表示されます。これは、彼らが同じシンボルを定義していることを最初に発見したときです。OpenSSL を g++ で再コンパイルして、現時点で名前空間にドロップしようとしています...以下の編集を参照してください...

  2. SDK のみとリンクします。自分のコードが依存する未定義のシンボルを取得します。これは、サードパーティの lib の再コンパイルがサブセットであるか、少なくとも 1 つのモジュールが無効に設定されていることがわかったときです。

  3. サードパーティのライブラリのみとリンクします。SDK によって報告された未定義のシンボルがいくつかあります。そのうちの 1 つは実際にはサード パーティ ライブラリ内のヘッダー ファイルの #define であるため、サード パーティ ライブラリ内のすべての参照は定義に解決されますが、外部の参照は解決されません。私はそれをcファイルに移動しました。これにより解決されますが、どこにも見つからない未解決の関数が2つあります。これは私がこれまでに得た中で最も近いものです。

  4. 競合するシンボルを 1 つのライブラリから削除し、両方のリンクをリンクします。これまでのところ、これは機能していません。SDK で静的にリンクされた lib と、サードパーティの lib を使用してみたバージョンとの間のバージョンの問題である可能性がありますが、一部の関数がシンボル間で移動されているように見えるため、シンボルを削除することで、うっかり削除してしまいました他の場所で必要な機能。SDK のシンボル内の関数とサードパーティ ライブラリ内のシンボル内の関数との間の完全なマッピングはないようです。アドレスを手動で調整せずに機能を削除することは妥当ですか?

私はライブラリ内のシンボルを次のように調べてきました:

nm -C --defined-only lib<name>.a

そして、オブジェクト全体を次のように抽出します:

ar -x lib<name>.a <objname>.o

うまくいけば、これは、互いに競合するサードパーティのライブラリとリンクしなければならなかった他の人にも役立つでしょう. 詳細のために、サードパーティのライブラリはOpenSSLであり、SDK はOpsecです。libcpopenssl.a は Opsec の問題のあるライブラリです。

**編集 - 遅いエントリの可能な回避策は、OpenSSL を g++ で再コンパイルし、すべてを名前空間に配置してから、両方のライブラリをリンクすることです。私は今それを試みています...もっと来る...

4

2 に答える 2

3

Google 検索によると、SSL_get_peer_dh と DH_dup は実際には libcpopenssl.a からの追加であり、私の OpenSSL のコピーにも存在しません。そのため、そのライブラリを実際にリンクする必要があります。バイナリ レベルで両方のライブラリを混在させる (上記のアプローチ 4) ことはほとんどありません。 ) したがって、.a ファイルと ABI 互換の .so を持っていることは非常に幸運である必要があります。

私の提案はアプローチ 4 のバリエーションですが、ソース レベルでは、Opsec libcpopenssl.a にリンクがあります。これは、追加のシンボル (およびおそらく他の変更) を含む OpenSSL の修正バージョンであり、追加の機能を取得するためです。 OpenSSL ソースから必要とし、それらのオブジェクトを libcpopenssl.a で再コンパイルして、Opsec バージョンの機能を使用できるようにします。libcpopenssl.a によってエクスポートされない少数の OpenSSL 関数のみを使用している場合、これは非常に実行可能です。

確かに、これはまだ面倒なアプローチですが、もちろん、Opsec SDK が OpenSSL にセマンティックな変更を加えていないことを条件に、プロジェクトにプルしている追加の OpenSSL 関数を壊すことはありません。

(私は StackOverflow の初心者なので、この提案が適切な回答と見なされるかどうかはわかりませんが、とにかく、コメントを投稿するための評判ポイントがありません。不適切な場合は削除します。)

于 2012-11-03T03:14:41.867 に答える
1

病的に興味がある方のために説明すると、OpenSSL の最新バージョンでは 249 個のファイルが変更され、コンパイルできるようになっています。最も一般的な問題は、特に void* を使用した C スタイルのポインター キャストの多さです。今、夢の中で「reinterpret_cast」を見ています。

ただし、これだけでは解決しませんでした。名前空間全体に配置する必要があります。つまり、すべてのファイルと、それに対する私自身の内部参照を再度変更する必要があります。とりあえずこれで渡そうと思います。

みんな助けてくれてありがとう。

于 2012-11-06T22:21:04.043 に答える