2016-10-30 3 views
2

ich den Aufbau einer Wrapper/Schnittstelle für eine C-Bibliothek mit Swift 3. Eine der Funktionen, die ich anrufen müssen hat einen Funktionszeiger erfordern für Rückruf als Argument.eine C-API-Funktion in Swift 3 verwenden, die eine Rückruffunktion Zeiger als Argument

Im Detail: nach der Funktion erfolgreich die Dateioperation sie hat getan hat, dann ruft die Funktion das gegebene Argument Zeiger verweist - im Wesentlichen dass ich andere Operationen tun mit den Daten

Die Funktion sieht dies wie:

HSYNC MXDEF (Syncer)(DWORD h, DWORD t, QWORD p, SYNCPROC *proc, void *user);

Die Callback-Funktion Typ SYNCPROC wie folgt definiert ist:

typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void *user);

Ich habe nur in der Lage gewesen, mit der Einstellung des Callback-Arguments nil bisher die Syncer Funktion zu verwenden.

Ich habe versucht, eine Funktion außerhalb der Klasse erstellen, wie jemand vorgeschlagen:

func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer) -> Void { print("callback called") }

Und ich auch diese Methode in der Klasse versucht:

var callbackTest : @convention(c) (_ handle: HSYNC, _ channel: DWORD, _ data: DWORD, _ user: UnsafeMutableRawPointer) -> Void = { print("\($0) \($1) \($2) \($3)") }

Aber so habe ich versucht,/lesen bei diesem Thema, das ich immer mit dieser Fehlermeldung am Ende:

Cannot convert value of type 'Void' (aka '()') to expected argument type '(@convention(c) (HSYNC, DWORD, DWORD, UnsafeMutableRawPointer?) -> Void)!'

Meine Frage ist: Wie soll ich die Kriterien in Bezug auf diese Art einer Callback-Funktion erfüllen?

Ich habe nicht in der Lage gewesen, irgendwelche Informationen über diese Art von Callback-Funktionen zu finden, was vermutlich auf meinen Mangel an Wissen und tiefen Verständnis des Problems. Vielen Dank im Voraus!

Antwort

2

eine globale Funktion Passing als Callback sollte funktionieren, aber der letzte Parameter muss ein optionales UnsafeMutableRawPointer? sein:

func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer?) -> Void { 
    print("callback called") 
} 

Syncer(h, c, d, callbackCalled, u) 

Alternativ passieren einen Verschluss Ausdruck (und lassen Compiler schließen die Typen der Parameter):

Syncer(h, d, c, { 
    (handle, channel, data, user) in 
    // ... 
}, u) 

Sie können keine Instanz Methode als Callback übergeben, vergleichen, How to use instance method as callback for function which takes only func or literal closure.

Wenn NULL ist kein gültiger Wert für den Benutzerparameter können Sie "Nullability annotations" auf die C-Deklaration hinzuzufügen, z.B.

typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void * _Nonnull user); 

und dann wird es als nicht-optionale UnsafeMutableRawPointer in Swift dargestellt werden.

+0

Vielen Dank für die tolle und schnelle Hilfe noch einmal! Ich habe die Syntax vermasselt - jetzt funktioniert es perfekt. – drummingdemon

Verwandte Themen