Is there a C++ library you’d like to consume in your iOS application? C++ is a low level programming language that has been around for over 35 years now.
您想在iOS应用程序中使用C ++库吗? C ++是一种低级编程语言,至今已有35多年的历史了。
Whilst C++ is a very old and complicated language and it is still very much relevant in todays world. C++ is predominantly used when higher performance is required. Examples of such libraries are Unreal Engine for gaming and OpenCV for live computer vision.
尽管C ++是一种非常古老且复杂的语言,但在当今世界中仍然非常重要。 当需要更高的性能时,主要使用C ++。 此类库的示例包括用于游戏的虚幻引擎和用于实时计算机视觉的OpenCV。
In fact Apple still employs C++ to write some of its most popular and performance requiring features. Rumour is that the Animoji feature is written in C++.
实际上,Apple仍使用C ++来编写其一些最流行且对性能有要求的功能。 有传言说Animoji功能是用C ++编写的。
If you are building some C++ features in you Swift iOS app then consuming C++ from Swift is no straight forward task.
如果您要在Swift iOS应用中构建一些C ++功能,那么从Swift消费C ++并不是直接的任务。
This post is about how to consume C++ code from Swift. I assume you know the basics of iOS development, Swift programming and Object Oriented Programming.
这篇文章是关于如何使用Swift中的C ++代码。 我假设您了解iOS开发,Swift编程和面向对象编程的基础。
You don’t really need to know C++ programming. Just the basics of Object Oriented Programming. The C++ code that I will use in this post is very basic and easy to grasp. This is not a tutorial to show you how to program with C++.
您实际上不需要了解C ++编程。 只是面向对象编程的基础。 我将在本文中使用的C ++代码非常基础且易于掌握。 这不是向您展示如何使用C ++进行编程的教程。
In this tutorial I’ll first cover on a high level how consumption of C++ from Swift works. We’ll then create a SwiftUI app from scratch. We’ll then add some C++ that returns “Hello from CPP world!” message. Finally we’ll retrieve the “Hello from CPP world!” message and display it to the user.
在本教程中,我将首先简要介绍Swift使用C ++的工作原理。 然后,我们将从头开始创建一个SwiftUI应用。 然后,我们将添加一些返回“ CPP世界您好!”的C ++。 信息。 最后,我们将检索“ CPP世界您好!” 消息并显示给用户。
I have used Swift 5.2.4 and Xcode 12.0 beta whilst writing this article.
在撰写本文时,我使用了Swift 5.2.4和Xcode 12.0 beta。
In essence Swift can’t consume C++ code directly. However Swift is capable of consuming Objective-C code and Objective-C (more specifically its variant Objective-C++) code is able to consume C++. Hence in order for Swift code to consume C++ code we must create an Objective-C wrapper or bridging code.
本质上,Swift不能直接使用C ++代码。 但是Swift可以使用Objective-C代码,而Objective-C(更具体地讲,其变体的Objective-C ++)代码也可以使用C ++。 因此,为了使Swift代码能够使用C ++代码,我们必须创建一个Objective-C包装程序或桥接代码。
Ana Movileanu Ana Movileanu设计In this section we will:
在本节中,我们将:
Create a iOS SwiftUI app from scratch 从头开始创建iOS SwiftUI应用 Add C++ code添加C ++代码Create C++ Bridging code创建C ++桥接代码Consume C++ code from Swift从Swift消费C ++代码Let’s begin by creating a new SwiftUI app for iOS. Open Xcode and then from menu select File > New > Project…
让我们开始为iOS创建一个新的SwiftUI应用。 打开Xcode,然后从菜单中选择File > New > Project…
Create a new project 创建一个新项目Next from iOS template select App. Click Next.
接下来从iOS模板中选择App 。 单击下一步。
use the iOS app template 使用iOS应用模板Then on “Choose options for your new project” prompt call the app SwiftCPP. Make sure the “Interface:” option is SwiftUI, “Life Cycle:” is SwiftUI App and finally the “Language:” is set to Swift. All checkboxes can be left unchecked. Click Next.
然后在“为新项目选择选项”上,提示应用程序SwiftCPP 。 确保“界面:”选项为SwiftUI ,“生命周期:”为SwiftUI App ,最后将“语言:”设置为Swift 。 所有复选框都可以不选中。 单击下一步。
new project options window 新项目选项窗口Then navigate to a folder where you’d like to store your project. Finally click Create.
然后导航到要存储项目的文件夹。 最后单击创建。
Next let’s ad some C++ code. From menu select File > New > File… When prompted “Choose a template for your new file” search and select C++ File under the iOS tab. Then click Next.
接下来,我们添加一些C ++代码。 从菜单中选择文件>新建>文件…,当系统提示“选择新文件的模板”时,搜索并在iOS标签下选择C ++文件。 然后单击“下一步” 。
Next name the file HelloWorld and check “Also create a header file”. Click Next.
接下来,将文件命名为HelloWorld并选中“同时创建头文件”。 单击下一步。
Finally click Create.
最后单击创建。
When prompted “Would you like to configure an Objective-C bridging header?” click Create Bridging Header.
当提示“您是否要配置一个Objective-C桥接头吗?” 点击创建桥接标题。
The bridging header is where we’ll specify Xcode which Objective-C code we want to be consumed from Swift later in this tutorial.
在桥接头文件中,我们将在本教程的后面部分指定Xcode我们想要从Swift中使用的Objective-C代码。
Next let’s add some C++ code to our HelloWorld files. First let’s open the header file; HelloWorld.hpp. In simple terms the header file is like the protocol or interface.
接下来,让我们向HelloWorld文件中添加一些C ++代码。 首先让我们打开头文件; HelloWorld.hpp 。 简单来说,头文件就像协议或接口。
Add the following code under #include <stdio.h> :
在#include <stdio.h>下添加以下代码:
#include <string>class HelloWorld {public: std::string sayHello();};Next let’s add the implementation of the HelloWorld interface. Open HelloWorld.cpp and under #include "HelloWorld.hpp" add the following code:
接下来,让我们添加HelloWorld接口的实现。 打开HelloWorld.cpp并在#include "HelloWorld.hpp"添加以下代码:
std::string HelloWorld::sayHello() { return "Hello from CPP world!";}As mentioned earlier in the “How consuming C++ code from Swift works?” section, we aren’t able to consume C++ code from Swift directly. Rather Swift can consume Objective-C and Objective-C can consume C++.
如前所述,“如何使用Swift中的C ++代码?” 部分,我们无法直接使用Swift中的C ++代码。 相反,Swift可以使用Objective-C,而Objective-C可以使用C ++。
Thus in section we’ll create a wrapper or bridging code between Swift and C++ in Objective-C.
因此,在本节中,我们将在Objective-C中的Swift和C ++之间创建包装或桥接代码。
Let’s add a new file. From menu select File > New > File… Next search and select Header File from the iOS tab. Click Next.
让我们添加一个新文件。 从菜单中选择文件>新建>文件…下一步搜索,然后从iOS选项卡中选择头文件。 单击下一步。
Name the file HelloWorldWrapper then click Create. Replace the file content to the following:
将文件命名为HelloWorldWrapper,然后单击创建。 将文件内容替换为以下内容:
#import <Foundation/Foundation.h>@interface HelloWorldWrapper : NSObject- (NSString *) sayHello;@endNext let’s create the implementation file of the HelloWorldWrapper interface. From menu select File > New > File… Then search and select Objective-C File from the iOS tab. Click Next.
接下来,让我们创建HelloWorldWrapper接口的实现文件。 从菜单中选择文件>新建>文件…,然后在iOS选项卡中搜索并选择Objective-C文件。 单击下一步。
Next name the file HelloWorldWrapper and click Next. Finally click Create.
接下来,将文件命名为HelloWorldWrapper ,然后单击“下一步” 。 最后单击创建。
Next change the file name from HelloWorldWrapper.m to HelloWorldWrapper.mm. Yes that is 2 m’s, it’s not a typo. The second “m” signals Xcode and the compiler that this Objective-C file will use C++ code.
接下来,将文件名从HelloWorldWrapper.m更改为HelloWorldWrapper.mm 。 是的,那是2 m ,不是错字。 第二个“ m”表示Xcode和编译器此Objective-C文件将使用C ++代码。
Add an “m” to the extension of the file name 在文件名的扩展名中添加“ m”Next under #import <Foundation/Foundation.h> statement add the following code:
接下来,在#import <Foundation/Foundation.h>语句下添加以下代码:
#import "HelloWorldWrapper.h"#import "HelloWorld.hpp"@implementation HelloWorldWrapper- (NSString *) sayHello { HelloWorld helloWorld; std::string helloWorldMessage = helloWorld.sayHello(); return [NSString stringWithCString:helloWorldMessage.c_str() encoding:NSUTF8StringEncoding];}@endAbove we are simply calling the C++ code and converting a C++ string to an Objective-C NSString.
在上面,我们只是简单地调用C ++代码并将C ++ string转换为Objective-C NSString 。
Now that we have our C++ code wrapped in Objective-C, the Objective-C wrapper is not quite ready to be consumed. First we have to tell Xcode that we wish to consume the Objective-C code in Swift.
现在,我们已将C ++代码包装在Objective-C中,但还没准备好使用Objective-C包装器。 首先,我们必须告诉Xcode我们希望在Swift中使用Objective-C代码。
To do this we must the auto created SwiftCPP-Bridging-Header.h and add the following line:
为此,我们必须自动创建SwiftCPP-Bridging-Header.h并添加以下行:
#import "HelloWorldWrapper.h"This tell Xcode to automatically create a Swift binding interface for the HelloWorldWrapper Objective-C code.
这告诉Xcode为HelloWorldWrapper Objective-C代码自动创建Swift绑定接口。
Now we are ready to consume the Objective-C code. Open ContentView.swift and the following code:
现在,我们准备使用Objective-C代码。 打开ContentView.swift和以下代码:
struct ContentView: View { var body: some View { Text("Hello, world!").padding() }}to:
至:
struct ContentView: View { var body: some View { Text(HelloWorldWrapper().sayHello()).padding() }}The difference here is that instead of displaying "Hello, world!" we are now retrieving the message from the Objective-C HelloWorld wrapper by calling HelloWorldWrapper().sayHello().
区别在于,这里没有显示"Hello, world!" 我们现在通过调用HelloWorldWrapper().sayHello()从Objective-C HelloWorld包装器中检索消息。
Thats it! Run the app on a simulator and see it working. We are consuming C++ code from Swift! 🎉
而已! 在模拟器上运行该应用程序,然后查看其是否正常运行。 我们正在使用Swift中的C ++代码! 🎉
In this post we learnt:
在这篇文章中,我们学习了:
How to consume C++ from Swift 如何从Swift使用C ++You can find the full source code below:
您可以在下面找到完整的源代码:
In the past I have been using OpenCV quite a lot, for which I need to consume C++ code from Swift. Whilst iOS can take machine learning models or use already created models through CoreML and Vision framework I still prefer to do some low level computer vision algorithms using OpenCV in some specific scenarios. That is because already off the shelf libraries and models do not always live up to the performance requirements.
过去我经常使用OpenCV,为此我需要使用Swift中的C ++代码。 虽然iOS可以采用机器学习模型或通过CoreML和Vision框架使用已经创建的模型,但我仍然更喜欢在某些特定情况下使用OpenCV进行一些底层计算机视觉算法。 这是因为已经存在的库和模型并不总是符合性能要求。
Here are is an example of using OpenCV in iOS:
这是在iOS中使用OpenCV示例:
For more on iOS development follow me on Twitter or Medium!
有关iOS开发的更多信息,请在Twitter或Medium中关注我!
翻译自: https://medium.com/@anuragajwani/how-to-consume-c-code-in-swift-b4d64a04e989
相关资源:快速排序C语言代码