眾所周知,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 開發中都可以使用。