Yanıtlar:
Evet, elbette Apples C kütüphaneleriyle etkileşime geçebilirsiniz. İşte nasıl açıklanır.
Temel olarak, C tipleri, C işaretçileri vb. Swift nesnelerine çevrilir, örneğin int
Swift'teki C bir a CInt
.
C ve Swift arasında nasıl köprü kurulacağına dair küçük bir açıklama olarak kullanılabilecek başka bir soru için küçük bir örnek oluşturdum:
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-Köprü-Header.h
void getInput(int *output);
İşte orijinal cevap.
Derleyici, Objective-C için olduğu gibi C API'sini Swift'e dönüştürür.
import Cocoa
let frame = CGRect(x: 10, y: 10, width: 100, height: 100)
import Darwin
for _ in 1..10 {
println(rand() % 100)
}
Bkz . Dokümanlardaki Objective-C API'leriyle Etkileşim .
CFTypeRef
) Swift nesnelerine dönüştürülür. Ancak ObjCRuntime.h işlevlerinin çoğu Swift için anlamlı değildir.
Benim gibi XCode'da yeni olmanız ve Leandro'nun cevabında yayınlanan parçacıkları denemek istiyorsanız :
Bu yazı ayrıca clang'ın modül desteğini kullanarak bunun nasıl yapılacağı hakkında iyi bir açıklamaya sahiptir .
Bu, CommonCrypto projesi için nasıl yapılacağı açısından çerçevelenmiştir, ancak genel olarak Swift içinden kullanmak istediğiniz diğer C kitaplıkları için çalışması gerekir.
Kısaca zlib için bunu denedim. Yeni bir iOS çerçeve projesi oluşturdum ve aşağıdaki ile bir module.modulemap dosyası içeren bir zlib dizini oluşturdum:
module zlib [system] [extern_c] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/zlib.h"
export *
}
Sonra Hedefler -> İkili Kitaplıklarıyla Bağla altında öğe ekle ve libz.tbd ekledim.
Bu noktada inşa etmek isteyebilirsiniz.
Daha sonra aşağıdaki kodu yazabildim:
import zlib
public class Zlib {
public class func zlibCompileFlags() -> UInt {
return zlib.zlibCompileFlags()
}
}
Sen yok olması C işleviyle aynı fonk Swift sınıf adında yukarıdaki vaka I haricinde önünde zlib kitaplık adını koymak ve yeterlilik olmadan Swift fonk uçları uygulama alıkoymalarla kadar tekrar tekrar çağrılan.
C ++ durumunda, açılan bu hata vardır:
"_getInput", referenced from:
Bir c ++ başlık dosyasına da ihtiyacınız var. Ekle c-bağlantı fonksiyonunuza, ardından köprü başlığında başlık dosyasını içerir:
Hızlı 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-Köprü-Header.h
#include "UserInput.h"
İşte bunu açıklayan orijinal video
__OBJC
Bridging-Header'ınıza çek eklemeyi deneyin , örn.#ifdef __OBJC @import UIKit; #endif
İşaretçilerle uğraşırken oldukça farklı bir top balmumu gibi görünüyor. Şimdiye kadar C POSIX read
sistem çağrısı çağırmak için ne var :
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
}