はこれを行うことができる方法の単純化しすぎている例Richardが提案したObjective-C++ラッパーを使用しています。メモリ管理やスレッドの安全性など、ここでは扱いません。この例では、SwiftインスタンスとC++クラスインスタンスの間に1対1の関係があります。またSwiftオブジェクトポインタは識別子として使用され、どのSwiftオブジェクトが通知を受け取るべきかを決定します。これは危険です。下のコードのコメントを参照してください。 Objective-C++ラッパーのより洗練されたデータ構造を使用して、SwiftオブジェクトとC++オブジェクトの間の接続を維持すると、この危険を回避し、1対1以外の関係を容易にサポートできます。
まず第一に、ここでスウィフトコードの変更をトリガーするC++クラスがある:ここ
typedef void (*cb_t)(const char *, void *);
class MyClassCPP {
public:
MyClassCPP(cb_t callBack, void * p) : myCallBack(callBack), clientPtr(p) {}
void doWork(); // perform some work and invoke the callback
private:
cb_t myCallBack;
void * clientPtr;
};
void MyClassCPP::doWork() {
myCallBack("C++ code at work...", clientPtr);
}
直接、架橋ヘッダ介しスウィフトコードに可視化されるべき目的-C++ラッパーインタフェースであるか、または間接的にC++の型は参照していないことに注意してください。
@class SwiftClass; // forward declaration
// can't include *-Swift.h in a header
@interface OCWrapper : NSObject
-(instancetype)init:(SwiftClass *)sc;
-(void)requestWorkFromCPP;
@end
ここにラッパーの実装があります。これはC++型を参照します。 Swiftグローバル関数をC++コードのコールバックとして提供することはできませんが、この目的のためにObjective-C++グローバル関数を提供することができます。
// Extension that deals with C++ specifics that can't be visible to Swift
@interface OCWrapper()
{
MyClassCPP * myClassCPP;
}
@end
void callBack(const char * msg, void * swiftClient)
{
// Danger: what if swiftClient does not point to a SwiftClass instance?
[(__bridge SwiftClass*)swiftClient sayHello:
[[NSString alloc] initWithBytes: msg length:strlen(msg)
encoding:NSASCIIStringEncoding]];
}
@implementation OCWrapper
-(instancetype)init:(SwiftClass *)sc
{
myClassCPP = new MyClassCPP(callBack, (__bridge void*)sc);
return self;
}
-(void)requestWorkFromCPP{
myClassCPP->doWork();
}
@end
上記はObjective-C++ファイルにある必要があります。 Objective-Cファイルを作成し、ファイル名を.mm
に変更します。 Objective-C++がSwift型を使用できるように、* -Swift.hヘッダーも含める必要があります。
は最後に、ここでのObjective-C++ラッパーを経由してC++のコードを使用して、いくつかのスウィフトコードは次のとおりです。
// This is like your Swift view controller
class SwiftClass : NSObject
{
var label = "[Empty]"
var name : String;
init(name : String) {
self.name = name
}
func sayHello(greeting : String) {
label = "SwiftClass named " + name + " received greeting: " + greeting
}
}
...
let sc = SwiftClass(name : "Zero")
let ocWrapper = OCWrapper(sc)
let sc1 = SwiftClass(name : "One")
let ocWrapper1 = OCWrapper(sc1)
ocWrapper1.requestWorkFromCPP()
print("The label value from C++: \(sc1.label)")
ocWrapper.requestWorkFromCPP()
print("The label value from C++: \(sc.label)")
...
私はすべての私のSWIFT/C++ Objective-Cの++サンクを介して通信を行います。 –
あなたがここに誰かに遭遇している問題を示す簡単なコードスニペットを提供できれば、あなたを助けることができるかもしれません。 – OmniProg
@OmniProg:役に立つと思われるもの(ヘッダファイルを省略したもの)の例をいくつか追加しましたが、同様の方法で動作するとは思われません。これをアーカイブする方法はありますか? 'event in cpp-class' - >' swift-method'を呼び出す - > 'ラベル値を変更する '(例として)? – archimedes