iOS開發 - 在 Swift 中去呼叫 C/C++ 程式碼

語言: CN / TW / HK

眾所周知,Swift 是不能直接呼叫 C/C++ 程式碼的,而 Objective-C 是可以直接呼叫的。

想要 Swift 呼叫 C++ 方法,需要走 Objective-C 中轉才行,類似於 Java 呼叫 C++ 程式碼需要走 JNI 一樣。

反而 Swift 呼叫 C 方法還要簡單一些,不需要 Objective-C 中轉,以下就是具體操作詳情~

Swift 呼叫 C 程式碼

首先定義好 C 語言對應 .h 標頭檔案和 .c 實現檔案。

標頭檔案如下:

#ifndef CTest_h
#define CTest_h

#include <stdio.h>

// 定義一個方法
void test();

#endif /* CTest_h */
複製程式碼

實現檔案如下:

#include "CTest.h"

void test(){
    printf("swift call from c\n");
}
複製程式碼

內容很簡單,就是列印一個字串而已。

注意,當我們通過 XCode 來建立 C 檔案時,會有如下的彈框:

這個彈框非常重要啦,它會幫我們實現 Swift 和 C 之間的連結。

在專案配置裡面能看到對應的連結檔案說明,在 Swift 編譯時會把它編譯進去的。

我們要在這個彈框建立的標頭檔案裡把上面的 C 程式碼標頭檔案通過 import 包含進入,也就是實現下面的程式碼:

#import "CTest.h"
複製程式碼

然後就可以在 Swift 中愉快地呼叫 C 函式啦~~

Swift 裡面直接呼叫 C 語言函式就好啦,也不需要額外 import 什麼庫了。

Swift 呼叫 C++ 程式碼

Swift 呼叫 C++ 程式碼和呼叫 C 程式碼基本一致,就是要通過 Objective-C 來做一下中轉了,如下圖所示:

首先還是先建立好對應的 C++ .h 標頭檔案和 .cpp 實現檔案。

標頭檔案如下:

#ifndef CppTest_h
#define CppTest_h

#include <iostream>
class CppTest{
public:
    void test();
};
#endif /* CppTest_h */
複製程式碼

實現檔案如下:

#include "CppTest.h"

void CppTest::test(){
    printf("swift call from c++\n");
}
複製程式碼

重點來了,在 XCode 中建立 Objective-C 檔案來做中轉,同時要將建立的 .m 檔案字尾改成 .mm ,也就是字尾兩個 m 的檔案,這是告訴 XCode 編譯該檔案時要用到 C++ 程式碼。

在中轉的 Objective-C 檔案程式碼中實現如下內容:

Objective-C 的標頭檔案宣告一個方法:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CppTestWrapper : NSObject

-(void) testcpp;

@end

NS_ASSUME_NONNULL_END
複製程式碼

Objective-C 的 .mm 檔案實現該方法:

#import "CppTestWrapper.h"
#import "CppTest.h"
#import <memory>

@implementation CppTestWrapper

-(void)testcpp{
    auto sp = std::make_shared<CppTest>();
    sp->test();
}
@end
複製程式碼

這裡用到了 C++ 檔案,所以要用 import 包含進來,然後就可以宣告並建立 C++ 類了。

接下來要在負責連結的標頭檔案中匯入上面的 Objective-C,主要是匯入 Objective-C 標頭檔案而不是 C++ 的標頭檔案,這和呼叫 C 語言方法還是不一樣的。

// 呼叫 C 就匯入 C 標頭檔案
#import "CTest.h"
// 呼叫 C++ 匯入 Objective-C 標頭檔案
#import "CppTestWrapper.h"
複製程式碼

接下來就可以在 Swift 中呼叫 Objective-C 從而間接呼叫 C++ 程式碼啦。

如上圖所示,先是建立了 Objective-C 物件,然後再呼叫其方法。

通過上述操作就可以愉快地呼叫 C++ 程式碼啦~~

以上方案經過實踐在 iOS 和 macOS 開發中都可以使用。

參考

  1. medium.com/@anuragajwa…
  2. www.youtube.com/watch?v=Ssq…