스위프트에서 C로 전화하려면 어떻게 해야 하나요?
스위프트에서 C 루틴을 호출할 수 있는 방법이 있나요?
iOS/Apple 라이브러리의 대부분은 C뿐이며, 아직 호출할 수 있습니다.
예를 들어 swift에서 objc 런타임 라이브러리를 호출할 수 있으면 좋겠습니다.
특히 iOS C 헤더를 브리지하려면 어떻게 해야 합니까?
네, 물론 Apple의 C 라이브러리와 상호 작용할 수 있습니다.방법은 다음과 같습니다.
기본적으로 C 타입, C 포인터 등은 Swift 오브젝트(예를 들어 C)로 변환됩니다.int
Swift는CInt
.
C와 Swift를 연결하는 방법에 대한 간단한 설명으로 사용할 수 있는 또 다른 질문을 위해 아주 작은 예를 만들었습니다.
main.discloss.main.discloss.
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);
정답은 여기 있습니다.
컴파일러는 Objective-C와 마찬가지로 C API를 Swift로 변환합니다.
import Cocoa
let frame = CGRect(x: 10, y: 10, width: 100, height: 100)
import Darwin
for _ in 1..10 {
println(rand() % 100)
}
문서의 Objective-C API와의 상호작용을 참조하십시오.
만약 당신이 나만큼 XCode에 처음이고, Leandro의 답변에 올라온 단편들을 시험해 보고 싶다면:
- 파일 -> 신규 -> 프로젝트
- 프로젝트 프리셋으로 명령줄 도구를 선택하고 프로젝트 이름을 "cliinput"으로 지정합니다.
- 프로젝트 탐색기(왼쪽 파란색 패널)를 마우스 오른쪽 버튼으로 클릭하고 "새 파일..."
- 드롭다운 대화상자에서 파일 이름을 "UserInput"으로 지정합니다."헤더 파일도 작성" 상자의 선택을 취소합니다.[Next] (다음)을 클릭하면 XCode가 Bridging-Header.h 파일을 작성해야 하는지 여부를 묻습니다."예"를 선택합니다.
- 위의 Leandro 답변에서 코드를 복사하여 붙여넣습니다.재생 버튼을 클릭하면 xcode가 하단 패널에 내장된 터미널에서 컴파일 및 실행됩니다.단말기에 번호를 입력하면 번호가 반환됩니다.
이 게시물에서는 clang의 모듈 지원을 사용하여 이를 수행하는 방법에 대해서도 설명합니다.
CommonCrypto 프로젝트에서 이 작업을 수행하는 방법에 대한 프레임이지만 일반적으로 Swift 내에서 사용하고 싶은 다른 C 라이브러리에서 작동합니다.
zlib을 위해서 잠깐 실험을 해봤습니다.새로운 iOS 프레임워크 프로젝트를 만들고 다음과 같은 module.modulemap 파일을 포함하는 zlib 디렉토리를 만들었습니다.
module zlib [system] [extern_c] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/zlib.h"
export *
}
그런 다음 [Targets]-> [ Link Binary With Libraries ](라이브러리와 바이너리 연결)에서 추가 항목을 선택하고 libz.tbd를 추가합니다.
이 시점에서 빌드하는 것이 좋습니다.
그 후, 이하의 코드를 쓸 수 있었습니다.
import zlib
public class Zlib {
public class func zlibCompileFlags() -> UInt {
return zlib.zlibCompileFlags()
}
}
zlib 라이브러리 이름을 앞에 둘 필요는 없습니다.단, 위의 경우 Swift 클래스 펑크를 C 함수와 동일하게 명명하고 조건 없이 Swift 펑크는 애플리케이션이 정지할 때까지 반복 호출됩니다.
c++ 의 경우는, 다음의 에러가 표시됩니다.
"_getInput", referenced from:
c++ 헤더 파일도 필요합니다.기능에 c-linkage를 추가한 후 브리지헤더에 헤더파일을 포함합니다.
스위프트 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.discloss.main.discloss.
import Foundation
var output: CInt = 0
getInput(&output)
print(output)
cliinput-Bridging-Header.h
#include "UserInput.h"
여기 이것을 설명하는 원본 비디오입니다.
포인터를 다룰 때는 좀 다른 볼 왁스처럼 보입니다.까지 C POSIX 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
}
언급URL : https://stackoverflow.com/questions/24004732/how-to-call-c-from-swift
'source' 카테고리의 다른 글
CSS 속성(컬러)을 VueJS 변수로 설정 (0) | 2022.08.19 |
---|---|
화살표 연산자 vs.도트 연산자 (0) | 2022.08.19 |
DUBLE_MAX 입수방법 (0) | 2022.08.19 |
필드 등급(vue js) 값을 전달하려면 어떻게 해야 합니까? (0) | 2022.08.19 |
HashMap - 첫 번째 키 값 가져오기 (0) | 2022.08.18 |