Odpowiedzi:
Tak, możesz oczywiście współdziałać z bibliotekami Apples C. Tutaj wyjaśniono, jak to zrobić.
Zasadniczo typy C, wskaźniki C itp. Są tłumaczone na obiekty języka Swift, na przykład C intw języku Swift to CInt.
Zbudowałem mały przykład dla innego pytania, które może być użyte jako małe wyjaśnienie, jak połączyć C i Swift:
main.swift
import Foundation
var output: CInt = 0
getInput(&output)
println(output)
UserInput.c
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
cliinput-Bridging-Header.h
void getInput(int *output);
Oto oryginalna odpowiedź.
Kompilator konwertuje C API na Swift, tak jak robi to dla Objective-C.
import Cocoa
let frame = CGRect(x: 10, y: 10, width: 100, height: 100)
import Darwin
for _ in 1..10 {
println(rand() % 100)
}
Zobacz Interakcja z interfejsami API Objective-C w dokumentacji.
CFTypeRef) w stylu CoreFoundation są konwertowane na obiekty Swift. Większość funkcji ObjCRuntime.h nie ma jednak znaczenia dla języka Swift.
Na wypadek, gdybyś był równie nowy w XCode jak ja i chciałbyś wypróbować fragmenty zamieszczone w odpowiedzi Leandro :
Ten post zawiera również dobre wyjaśnienie, jak to zrobić, korzystając z obsługi modułów clang .
Jest sformułowany pod kątem tego, jak to zrobić dla projektu CommonCrypto, ale ogólnie powinien działać dla każdej innej biblioteki C, z której chcesz korzystać w Swift.
Krótko eksperymentowałem z robieniem tego dla zlib. Stworzyłem nowy projekt platformy iOS i utworzyłem katalog zlib, zawierający plik module.modulemap zawierający:
module zlib [system] [extern_c] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/zlib.h"
export *
}
Następnie w obszarze Cele -> Połącz pliki binarne z bibliotekami wybrałem dodaj elementy i dodałem libz.tbd.
W tym momencie możesz chcieć zbudować.
Byłem wtedy w stanie napisać następujący kod:
import zlib
public class Zlib {
public class func zlibCompileFlags() -> UInt {
return zlib.zlibCompileFlags()
}
}
Nie musisz umieszczać nazwy biblioteki zlib na początku, z wyjątkiem powyższego przypadku, gdy nazwałem funkcję klasy Swift tak samo jak funkcję C, a bez kwalifikacji funkcja Swift jest wywoływana wielokrotnie, aż aplikacja się zatrzyma.
W przypadku C ++ pojawia się następujący błąd:
"_getInput", referenced from:
Potrzebujesz też pliku nagłówkowego C ++. Dodaj link-c do swojej funkcji, a następnie dołącz plik nagłówkowy do nagłówka mostu:
Szybki 3
UserInput.h
#ifndef USERINPUT_H
#define USERINPUT_H
#ifdef __cplusplus
extern "C"{
#endif
getInput(int *output);
#ifdef __cplusplus
}
#endif
UserInput.c
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
main.swift
import Foundation
var output: CInt = 0
getInput(&output)
print(output)
cliinput-Bridging-Header.h
#include "UserInput.h"
Oto oryginalny film wyjaśniający to
__OBJCczek do swojego nagłówka Bridging-Header, np.#ifdef __OBJC @import UIKit; #endif
Wydaje się, że to trochę inna kula wosku, gdy mamy do czynienia ze wskazówkami. Oto, co mam do tej pory do wywoływania wywołania readsystemowego C POSIX :
enum FileReadableStreamError : Error {
case failedOnRead
}
// Some help from: http://stackoverflow.com/questions/38983277/how-to-get-bytes-out-of-an-unsafemutablerawpointer
// and https://gist.github.com/kirsteins/6d6e96380db677169831
override func readBytes(size:UInt32) throws -> [UInt8]? {
guard let unsafeMutableRawPointer = malloc(Int(size)) else {
return nil
}
let numberBytesRead = read(fd, unsafeMutableRawPointer, Int(size))
if numberBytesRead < 0 {
free(unsafeMutableRawPointer)
throw FileReadableStreamError.failedOnRead
}
if numberBytesRead == 0 {
free(unsafeMutableRawPointer)
return nil
}
let unsafeBufferPointer = UnsafeBufferPointer(start: unsafeMutableRawPointer.assumingMemoryBound(to: UInt8.self), count: numberBytesRead)
let results = Array<UInt8>(unsafeBufferPointer)
free(unsafeMutableRawPointer)
return results
}