Wie kann ein C-Callback ein Objective-C-Objekt über einen Userdata-Zeiger zurückgeben?

8

Ich verwende eine Bibliothek eines Drittanbieters, die einen C-Rückruf in einem iOS-Programm erfordert. Der Rückruf bietet einen void* userdata-Parameter, den ich verwenden kann, wie ich es wünsche. In diesem Rückruf möchte ich ein NSData-Objekt erstellen, das an den Code zurückgegeben wird, der die API aufruft, die schließlich den Rückruf aufruft. Zum Beispiel:

%Vor%

Ich verwende ARC, was meiner Meinung nach die Ursache der Probleme ist. Ich dachte daran, eine Struktur zu verwenden, um die NSData* zu halten, aber ARC verbietet Objective-C-Objekte in Strukturen oder Vereinigungen. Es gibt wahrscheinlich eine Variante von __bridge , die helfen könnte, aber ich bin mir nicht sicher welche. Ich habe viele SO-Fragen angeschaut und die Apple-Dokumente gelesen, aber mir ist nicht klar, wie ich das programmieren soll.

Wenn d zum Zeitpunkt des Rückrufs idealerweise nicht null wäre, würde der aktuelle Wert freigegeben und ein neues NSData-Objekt würde ihn ersetzen. Mit anderen Worten, wenn library_api abgeschlossen ist, hält d immer das NSData-Objekt, das durch den Rückruf erstellt wurde, und jeder zuvor gehaltene Wert wäre korrekt freigegeben worden.

Ich nehme an, ich könnte den Objective-C-Code aus dem Callback heraushalten und nur malloc() einen Puffer, um die Daten zu speichern, die dann in ein NSData-Objekt im Hauptcode kopiert werden, aber ich hoffe, dass ich es vermeiden kann dieser zusätzliche Schritt.

    
Randall Cook 16.09.2013, 21:52
quelle

2 Antworten

4

Sie können Objekteigentum nicht auf ein void* übertragen, aber Sie können Objekteigentum auf einen CoreFoundation-Typ übertragen, wie CFDataRef oder CFTypeRef . Sie können dann den CF-Zeiger beliebig weiterleiten.

z.B.:

%Vor%

Und im Rückruf:

%Vor%     
Darren 16.09.2013, 22:50
quelle
1

Sie können struct ObjC Objekt haben, sie müssen nur __unretained_unsafe ODER in .mm Datei sein.

Es gibt wenige Optionen:

1 Verwenden Sie eine Struktur, um das ObjC-Objekt in der .m-Datei zu speichern

%Vor%

2 Verwenden Sie eine Struktur, um ObjC-Objekt in .mm -Datei (Objective-C ++) zu halten, und verwenden Sie C ++ new/delete für die Struktur. Sie können dies tun, weil der Compiler retain / release im Konstruktor / Destruktor der Struktur generiert.

%Vor%

3 Ändere die Signatur der Callback-Funktion und wirke sie (das habe ich vorher nicht versucht)

4 Machen Sie diese Datei nicht ARC mit -fno-objc-arc Compiler-Flag

    
Bryan Chen 16.09.2013 22:23
quelle