[解決済み] SwiftからC++のクラスとインタラクトする
質問
私はC++で書かれたクラスの重要なライブラリを持っています。 私は、Swift コードとしてそれらを書き直すのではなく、Swift 内のある種のブリッジを通してそれらを利用しようとしています。 主な動機は、C++のコードが、複数のプラットフォームで使用されるコアライブラリを表していることです。 事実上、私は、OS Xの下でコア機能が動作するように、SwiftベースのUIを作成しているだけです。
Swift から C++ の関数を呼び出すにはどうすればよいか、という他の質問もあります。 ではなく の質問ではありません。 C++の関数に橋渡しするために、以下はうまくいきます。
"C"を通してブリッジングヘッダを定義します。
#ifndef ImageReader_hpp
#define ImageReader_hpp
#ifdef __cplusplus
extern "C" {
#endif
const char *hexdump(char *filename);
const char *imageType(char *filename);
#ifdef __cplusplus
}
#endif
#endif /* ImageReader_hpp */
Swift のコードで関数を直接呼び出せるようになりました。
let type = String.fromCString(imageType(filename))
let dump = String.fromCString(hexdump(filename))
私の質問はより具体的です。 どのようにすれば C++クラス をSwift内からインスタンス化し、操作することができますか? 私はこれについて公開されたものを見つけることができないようです。
どのように解決するのですか?
私は完全に管理可能な答えを導き出しました。 どの程度きれいにしたいかは、あなたがどの程度の作業をしたいかによります。
まず、C++のクラスを取り出し、それとインターフェイスするためにCの"wrapper"関数を作成します。 例えば、このC++クラスがあるとします。
class MBR {
std::string filename;
public:
MBR (std::string filename);
const char *hexdump();
const char *imageType();
const char *bootCode();
const char *partitions();
private:
bool readFile(unsigned char *buffer, const unsigned int length);
};
次に、これらのC++の関数を実装します。
#include "MBR.hpp"
using namespace std;
const void * initialize(char *filename)
{
MBR *mbr = new MBR(filename);
return (void *)mbr;
}
const char *hexdump(const void *object)
{
MBR *mbr;
static char retval[2048];
mbr = (MBR *)object;
strcpy(retval, mbr -> hexdump());
return retval;
}
const char *imageType(const void *object)
{
MBR *mbr;
static char retval[256];
mbr = (MBR *)object;
strcpy(retval, mbr -> imageType());
return retval;
}
次に、ブリッジヘッダには
#ifndef ImageReader_hpp
#define ImageReader_hpp
#ifdef __cplusplus
extern "C" {
#endif
const void *initialize(char *filename);
const char *hexdump(const void *object);
const char *imageType(const void *object);
#ifdef __cplusplus
}
#endif
#endif /* ImageReader_hpp */
Swift からは、今、オブジェクトをインスタンス化し、このように対話することができます。
let cppObject = UnsafeMutablePointer<Void>(initialize(filename))
let type = String.fromCString(imageType(cppObject))
let dump = String.fromCString(hexdump(cppObject))
self.imageTypeLabel.stringValue = type!
self.dumpDisplay.stringValue = dump!
このように,(実際にはかなり単純な)解決策は,オブジェクトをインスタンス化し,そのオブジェクトへのポインタを返すラッパーを作成することです. このポインターはラッパー関数に戻され、ラッパー関数は簡単にそのクラスに準拠したオブジェクトとして扱い、メンバー関数を呼び出すことができます。
よりクリーンにする
これは素晴らしいスタートであり、些細なブリッジで既存のC++クラスを使用することが完全に実現可能であることを証明していますが、さらにクリーンなものにすることができます。
これをきれいにすることは、単に
UnsafeMutablePointer<Void>
を削除し、Swift クラスにカプセル化することです。 基本的に、私たちは同じ C/C++ ラッパー関数を使用しますが、Swift クラスでそれらをインターフェイス化します。 Swiftクラスは、オブジェクトの参照を維持し、本質的に、C++オブジェクトへのブリッジを通して、すべてのメソッドと属性参照の呼び出しを渡すだけです!Swiftクラスは、オブジェクトの参照を維持し、本質的に、すべてのメソッドと属性参照の呼び出しを渡すだけです。
これを行うことで、すべてのブリッジングコードはSwiftクラスで完全にカプセル化されます。 C ブリッジをまだ使用しているにもかかわらず、Objective-C または Objective-C++ でそれらを再コード化することなく、C++ オブジェクトを効果的に透過的に使用しています。
関連
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み] Swiftの@selector()?
-
[解決済み] Swiftのクラスにおける静的関数/変数とクラス関数/変数?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む