Ya, Anda tentu saja dapat berinteraksi dengan perpustakaan Apel C. Berikut dijelaskan caranya.
Pada dasarnya, tipe C, pointer C, dll diterjemahkan ke dalam objek Swift, misalnya C int
di Swift adalah a CInt
.
Saya telah membangun sebuah contoh kecil, untuk pertanyaan lain, yang dapat digunakan sebagai sedikit penjelasan, tentang bagaimana menjembatani antara C dan 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);
Inilah jawaban aslinya.
Kompilator mengubah C API menjadi Swift seperti yang dilakukannya untuk Objective-C.
import Cocoa let frame = CGRect(x: 10, y: 10, width: 100, height: 100) import Darwin for _ in 1..10 { println(rand() % 100) }
Lihat Berinteraksi dengan API Objective-C di dokumen.
sumber
CFTypeRef
) bergaya CoreFoundation dikonversi ke objek Swift. Sebagian besar fungsi ObjCRuntime.h tidak berarti bagi Swift.Untuk berjaga-jaga jika Anda baru mengenal XCode seperti saya dan ingin mencoba cuplikan yang diposting di jawaban Leandro :
sumber
Posting ini juga memiliki penjelasan yang bagus tentang bagaimana melakukan ini menggunakan dukungan modul clang .
Ini dibingkai dalam hal bagaimana melakukan ini untuk proyek CommonCrypto, tetapi secara umum itu harus berfungsi untuk pustaka C lain yang ingin Anda gunakan dari dalam Swift.
Saya secara singkat bereksperimen dengan melakukan ini untuk zlib. Saya membuat proyek framework iOS baru dan membuat direktori zlib, yang berisi file module.modulemap dengan berikut ini:
module zlib [system] [extern_c] { header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/zlib.h" export * }
Kemudian di bawah Target -> Link Binary With Libraries saya memilih menambahkan item dan menambahkan libz.tbd.
Anda mungkin ingin membangun pada saat ini.
Saya kemudian bisa menulis kode berikut:
import zlib public class Zlib { public class func zlibCompileFlags() -> UInt { return zlib.zlibCompileFlags() } }
Anda tidak harus meletakkan nama pustaka zlib di depan, kecuali dalam kasus di atas saya menamai kelas Swift func sama dengan fungsi C, dan tanpa kualifikasi fungsi Swift akhirnya dipanggil berulang kali sampai aplikasi berhenti.
sumber
Dalam kasus c ++, ada kesalahan ini yang muncul:
"_getInput", referenced from:
Anda juga membutuhkan file header c ++. Tambahkan c-linkage ke fungsi Anda, lalu sertakan file header di bridge-header:
Cepat 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"
Berikut adalah video asli yang menjelaskan hal ini
sumber
__OBJC
centang ke Bridging-Header Anda, misalnya#ifdef __OBJC @import UIKit; #endif
Tampaknya menjadi bola lilin yang agak berbeda saat berhadapan dengan pointer. Inilah yang saya miliki sejauh ini untuk memanggil panggilan sistem C POSIX
read
: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 }
sumber