如何在C語言中調用Swift函數

在Apple官方的《Using Swift with Cocoa and Objectgive-C》一書中詳細地介紹瞭如何在Objective-C中使用Swift的類以及如何在Swift中使用Objective-C中的類。在後半部分也介紹瞭如何在Swift中使用C函數,不過對於如何在C語言中使用Swift函數卻隻字未提。這裏我就爲你們分享一下如何在C語言中調用Swift函數。swift


咱們首先要知道的是,全部Swift函數都屬於閉包。其次,Swift函數的調用約定與Apple爲Clang編譯器貢獻的Blocks語法一致。所以,咱們須要經過使用Blocks調用約定將Swift函數導入到C語言中。因爲在C語言中沒法直接聲明Blocks調用約定的函數,所以咱們能夠經過定義全局的指向Blocks的對象指針來實現。閉包

下面咱們建立一個名爲SwiftTest的macOS系統上的Swift工程。而後新建一個名爲test.c的C源文件,若是Xcode沒有彈出是否新建bridging-header文件,那麼咱們能夠新增一個Objective-C源文件,最後把它給移除。這裏,咱們必須在工程裏包含SwiftTest-Bridging-Header.h這個頭文件。async

而後咱們編輯此頭文件:ide

extern void (^ __nonnull SwiftFunc)(void);
extern void CFuncTest(void);

這裏聲明的全局指向void(^)(void)類型的Block的引用對象。函數

而後咱們再看test.c源文件:測試

void (^SwiftFunc)(void) = NULL;

void CFuncTest(void)
{
    SwiftFunc();
}

咱們定義SwiftFunc全局對象,將它初始化爲空。spa

而後在ViewController.swift中編輯如下內容:指針

// 這裏是對SwiftFunc的實現
private func swiftFuncImpl() {
    print("This is a Swift function!");
}

class ViewController: NSViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // 這裏對定義在test.c中的SwiftFunc進行初始化
        SwiftFunc = swiftFuncImpl

        // 這裏用dispatch_async來測試SwiftFunc是否一直被hold着
        dispatch_async(dispatch_get_main_queue()) {
            
            CFuncTest()
        }
    }
}

當調用了test.c中定義的CFuncTest函數以後,該函數裏將直接調用SwiftFunc這一Block引用對象,從而達到了在C語言中調用了Swift中函數的目的。code

相關文章
相關標籤/搜索