如何从Swift呼叫C?
有没有办法从Swift调用C例程 很多iOS/Apple库都是C语言的,我仍然希望能够调用它们 例如,我希望能够从swift调用objc运行库如何从Swift呼叫C?,c,swift,C,Swift,有没有办法从Swift调用C例程 很多iOS/Apple库都是C语言的,我仍然希望能够调用它们 例如,我希望能够从swift调用objc运行库 特别是,如何桥接iOS C头?是的,您当然可以与苹果的C库交互。是如何解释的 基本上,C类型、C指针等被转换为Swift对象,例如Swift中的Cint就是一个CInt 我为另一个问题建立了一个小例子,这个问题可以作为一个小解释,关于如何在C和Swift之间架起桥梁: main.swift import Foundation var output: C
特别是,如何桥接iOS C头?是的,您当然可以与苹果的C库交互。是如何解释的 基本上,C类型、C指针等被转换为Swift对象,例如Swift中的C
int
就是一个CInt
我为另一个问题建立了一个小例子,这个问题可以作为一个小解释,关于如何在C和Swift之间架起桥梁:
main.swift
import Foundation
var output: CInt = 0
getInput(&output)
println(output)
import Foundation
var output: CInt = 0
getInput(&output)
print(output)
UserInput.c
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
是原始答案。编译器将C API转换为Swift,就像对Objective-C所做的一样
import Cocoa
let frame = CGRect(x: 10, y: 10, width: 100, height: 100)
import Darwin
for _ in 1..10 {
println(rand() % 100)
}
请参阅文档中的内容。以防您和我一样不熟悉XCode,想要尝试发布在中的代码片段:
module zlib [system] [extern_c] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/zlib.h"
export *
}
然后在Targets->linkbinary With Libraries下,我选择additems并添加libz.tbd
此时您可能需要构建
然后,我能够编写以下代码:
import zlib
public class Zlib {
public class func zlibCompileFlags() -> UInt {
return zlib.zlibCompileFlags()
}
}
您不必将zlib库名称放在前面,除非在上述情况下,我将Swift类func命名为与C函数相同的名称,并且在没有限定条件的情况下,Swift func最终会被重复调用,直到应用程序停止。在处理指针时,它似乎是一个完全不同的ball'o wax。以下是我到目前为止调用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
}
enum FileReadableStreamError:错误{
案例失败重新阅读
}
//一些帮助来自:http://stackoverflow.com/questions/38983277/how-to-get-bytes-out-of-an-unsafemutablerawpointer
//及https://gist.github.com/kirsteins/6d6e96380db677169831
重写函数读取字节(大小:UInt32)抛出->[UInt8]?{
guard let unsafeMutableRawPointer=malloc(Int(size))else{
归零
}
让numberBytesRead=read(fd,unsafeMutableRawPointer,Int(size))
如果numberBytesRead<0{
自由(非女性化指针)
抛出FileReadableStreamError.failedOnRead
}
如果numberBytesRead==0{
自由(非女性化指针)
归零
}
让unsafeBufferPointer=unsafeBufferPointer(开始:unsafeMutableRawPointer.assumingmemorybind(to:UInt8.self),计数:numberbytes读取)
让结果=数组(unsafeBufferPointer)
自由(非女性化指针)
返回结果
}
> > p>在C++的情况下,出现了这个错误:
"_getInput", referenced from:
你也需要一个C++头文件。添加到函数中,然后将头文件包括在桥接头中:
Swift 3
UserInput.h
void getInput(int *output);
#ifndef USERINPUT_H
#define USERINPUT_H
#ifdef __cplusplus
extern "C"{
#endif
getInput(int *output);
#ifdef __cplusplus
}
#endif
#include "UserInput.h"
UserInput.c
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
cliinput桥接头.h
void getInput(int *output);
#ifndef USERINPUT_H
#define USERINPUT_H
#ifdef __cplusplus
extern "C"{
#endif
getInput(int *output);
#ifdef __cplusplus
}
#endif
#include "UserInput.h"
这是原稿谢谢你的例子,你说得对,我可以看出这是怎么回事。然而,它并没有真正回答我的问题,即如何调用apple C库。但这绝对是最接近的。看看文件的其他地方。例如,CoreFoundation样式的“对象”(CFTypeRef
)将转换为Swift对象。但是,大多数ObjCRuntime.h函数对Swift没有意义?我想我需要找到一些方法导入一个标题并桥接它。这看起来很尴尬,但我想应该是这样。我对ios/swift还不熟悉。我想使用swift文件中包含的日志c函数。任何人?它与C++、.CPP文件兼容吗?直接使用C++文件,应该创建Objto-C包装器。您希望实现(它本身应该驻留在.mm文件中)包含Objto-C++代码(它只是一个文件中的Objto-C和C++),接口(应该在它自己的.h头文件)中应该包含纯ObjuleC代码,因此您必须在实现中将C++类型转换为Objy-C类型,把他们暴露给斯威夫特。然后,您可以使用objective-c桥接头导入该头。“您当然可以与Apple c库交互”不正确。您可以与任何C库进行交互,完全不限于Apple的。更新的文档链接如果不起作用,请尝试将\uuuuuujc
检查添加到桥接头,例如\ifdef\uuuuuujc@import UIKit#endif