2016-08-23 3 views
8

私はC++で巨大なlibを持っているとしましょう(多数の依存関係があり、GCCの完全ビルドで約3時間必要です)。私はそのライブラリを構築したいが、C++ではなく、より生産的な言語でそうしたいと思っている。 extern libパッケージを実際にブリッジするかラップすると、他の言語やプログラムでアクセスすることができますか?考えSwift/GoでのインポートのためのCへの巨大なC++ライブラリの自動添付

言語:

  • スウィフト
  • ゴー

何私が見つけたことは(私は実際に知らない両方の言語がCのLIBSとコードの自動ブリッジングまたはラッピングを提供しないということであり、ラッピング/ブリッジの違いは何ですか?)だから、私はいくつかのCコードを持っている場合、私はちょうど同じSwiftやGoプロジェクトでそれを投げることができ、私のプロジェクトで簡単なインポートでそれを使用することができます。

しかし、これは両方の言語でC++コードでは機能しません。だから私はどのようにCのコードにC + +のlibsを変換するか、またはautowrappersを生成するつもりだった。私は、次のが見つかりました: - C++のlibs

  • コモC++コンパイラの自動ラッパー -

    1. swig.org自動的にCコードにC++を転送し
    2. LLVM - に任意の入力を取得し、それを変換することができるはずです〜任意の出力LLVMが可能です。

    質問:自動折り返しを使用して

    1. はそれも 場合、スウィフト/ゴーのような他の言語でのこのような巨大なLIBの上に を構築する/使用可能な現実的/管理しやすいの王国ですか自動ブリッジ?
    2. 3つのリストされたlibs/programs/frameworkは、C++ - > Cの処理に最適です(SwiftとGoの両方がCの自動 ラッピングを提供するため)。
    3. 私は今まで考えていたものよりも優れた選択肢がありますか?
    4. "C++に固執する"方が良いでしょうか?他のツールを使ってラッピング/ブリッジ処理を行うのは、はるかに多いでしょうか? Swift/Goのように生産性の高い言語を使う利点がありますか?

    感謝:)

    免責事項:あり手動でCでのC++のlibをラップする可能性もあるが、それはこのような巨大なLIBのために仕事の耐え難い量を取るだろう。

  • +0

    ライブラリが言語相互運用性を考慮して設計されていない限り、これは、不可能ではないにしても、大きな可能性があります。主な課題は、オブジェクトのライフタイム管理(ホスト言語GCとの互換性)であり、すべての議論を単純なC表現に変えることです。もちろん、ライブラリは巨大ですが、APIが小さく、運が良ければ可能です。 – marangisto

    +0

    SWIGは非常に強力で、かなり複雑なシステムをラップすることができ、確かに大きなライブラリで作業することができます。それは自動的にはできません。SWIG * .iファイルを調整して調整する必要がありますが、SWIGは元の言語がどのようにラップされて公開されるかを定義する方法を提供するので、このような問題に対処するための強固な方法です新しい呼び出し言語に – stderr

    +0

    [cgogen](https://cgogen.com/)に興味があるかもしれません。 –

    答えて

    1

    Q1:現実的ですか?

    大規模で複雑なC++ interopは複雑すぎるため、現実的ではありません。自動ツールが失敗する可能性が高く、手作業が難しい可能性があります。

    質問2:ベストは何ですか?

    わかりませんが、A1を与えてもそれは問題ではないようです。

    Q3:代わりに? Q4:C++は最良の選択肢ですか?

    言語に関係なく、既存のC++コードを他の言語から利用したい場合、複雑なシナリオでは、ハイブリッドアプローチを使用することをお勧めします。

    ほとんどの言語は、非標準のC++命名規則のために、C++ではなくCにinteropを提供します。言い換えれば、ほぼすべての言語がプレーンなC関数へのアクセスを提供しますが、C++は頻繁にサポートされていません。

    ライブラリが複雑なため、最良の解決策は「ファサード」パターンに基づいています。新しいCライブラリを作成し、C++ライブラリを使用するアプリケーション固有のロジックを実装します。このライブラリを可能な限り薄く設計してください。目標は、すべてのビジネスロジックを記述するのではなく、C++オブジェクトを保持し、C++関数を呼び出すC関数を提供することです。 GOレベルの言語コードは、このライブラリを呼び出して、その下のC++ライブラリを使用します。このアプローチはQ1アプローチとは異なります。 Q1では、C++関数またはオブジェクトのメソッドごとに1つのinterop呼び出しを実行しようとします。 Facadeでは、アプリケーション固有のC++使用シナリオを実装しようとします。

    ファサードを使用すると、アプリケーションのシナリオを対象とするため、相互運用性の作業範囲を縮小できます。同時に、GO言語レベルでC++の複雑さを緩和します。

    たとえば、C++ライブラリを使用して温度センサーを読み取る必要があります。あなたがしなければならないだろうCで

    ++:

    1. 開いているファイル
    2. 読み取りストリームあなたがSLIPターミネータ

    1 "記録"

  • 近いファイルを読む見つけるまでファサードでは、 "readTemperature(deviceFileName)"という単一の関数を作成し、C関数は4回の呼び出しを同時に実行します。

    これは偽の例ですが、その点を示すだけです。

    ファサードを使用すると、元のC++オブジェクトを隠すことができ、この時点では小さなレイヤーになります。ここでの目標は、アプリケーションのニーズに焦点を当て、アプリケーションをサポートするための一般化とのバランスをとることです。

    興味深いことに、Facadeアプローチは、相互運用性のパフォーマンスを向上させる方法です。ほぼすべての言語のInteropは、langauageランタイム環境からマーシャリングして保護されている必要があるため、通常の操作よりも高価です。 interopコールがたくさんあるとアプリケーションが遅くなります(ここでは何百万人もの人が話しています)。たとえば、10 interopコールを1に組み合わせると、itnerop操作の量が減るため、パフォーマンスが向上します。

  • 関連する問題