[ad_1]
Interacting with C libraries from the Swift language is absolutely superb, from this submit can be taught probably the most of C interoperability.
Swift
From Swift 4 there’s native help for wrapping C libraries in Swift system module packages. This implies that you may eaily ship your individual system modules, you simply should learn to use the Swift Package deal Supervisor.😅
Bridging header inside Xcode
Let’s fireplace up Xcode and begin a model new single view app iOS venture. Fill out the required fields, and naturally select the Swift language. Subsequent, add a brand new file and select the C file template.
After you enter the identify and examine the additionally create header file field, Xcode will ask you in regards to the Goal-C bridging header file. Simply create it. The identify of this file is difficult, as a result of it additionally helps different C household langages, like pure C or C++, Goal-C and plus-plus. 😉
Let’s create a public header for the C code (factorial.h):
#ifndef factorial_h
#outline factorial_h
#embody <stdio.h>
lengthy factorial(int n);
#endif /* factorial_h */
That is gona be the implementation of the tactic (factorial.c):
#embody "factorial.h"
lengthy factorial(int n)
Contained in the bridging header, merely import the C header file:
#embody "factorial.h"
Someplace inside a Swift file you need to use the factorial technique:
print("Whats up (factorial(5))!")
Compile and run. 🔨 It simply works. 🌟 Magic! 🌟
You are able to do the very same factor to make use of Goal-C courses inside your Swift tasks. Apple has nice docs about this method, you must learn that if you wish to know extra about combine and match.
Delivery C code with SPM
The actual enjoyable begins while you begin utilizing the Swift Package deal Supervisor to construct C household primarily based sources. From Swift 3.0 you may construct C language targets with SPM. If you do not know use the SPM instrument, you must learn my complete tutorial in regards to the Swift Package deal Supervisor first.
The one factor that you will must do this can be a correct listing construction (plus you may want the package deal description file), and the package deal supervisor will take care all the remaining. Right here is every thing what it’s essential construct the factorial instance with SPM.
import PackageDescription
let package deal = Package deal(
identify: "cfactorial",
merchandise: [
.library(name: "cfactorial", targets: ["cfactorial"]),
],
targets: [
.target(
name: "cfactorial",
path: "./Sources/factorial"
),
]
)
The listing construction needs to be one thing like this.
Sources
factorial
embody
factorial.h
factorial.c
You must also change the #embody "factorial.h" line contained in the factorial.c file to #embody "embody/factorial.h" as a result of we made a brand new embody listing. That is NOT vital, however in the event you do not put your umbrella header into the embody listing, you may want to supply a modulemap file, and supply the proper location of your header. Should you use the embody construction SPM will generate every thing for you.
With this method you may import your cfactorial module from every other Swift package deal and name the factorial technique, like we did by way of Xcode. You simply have so as to add this module as a dependency, oh by the way in which you may even name this module from one other C venture made with SPM! 💥
.package deal(url: "https://gitlab.com/theswiftdev/cfactorial", .department("grasp")),
Congratulations, you simply shipped your first C code with Swift Package deal Supervisor. Please take a look at the instance repository, you may construct and run the venture by your self.
This setup additionally works with C, C++, Goal-C, Goal-C++ code.
Wrapping C [system] modules with SPM
If you wish to wrap a C [system] library and name it straight from Swift you may crete a model new wrapper package deal with the assistance of the Swift Package deal Supervisor. To begin you need to use the swift package deal init --type system-module command, this may create a generic template venture.
These are particular packages in keeping with Apple, you simply should ship your individual modulemap and a header file to show the wanted APIs, however first – clearly – you may want the standard package deal definition file:
import PackageDescription
let package deal = Package deal(
identify: "ccurl",
suppliers: [
.brew(["curl"]),
.apt(["libcurl4-openssl-dev"])
]
)
Contained in the Package deal.swift file you may set the suppliers for the library (like brew on macOS or aptitude for ubuntu / debian and the others). Right here is an efficient recommendation for you: sudo apt-get set up pkg-config underneath linux to make issues work, as a result of the system will seek for package deal header information with the assistance of the pkgConfig property. For instance if you wish to use libxml2 and pkg-config shouldn’t be put in, you will not have the ability to compile / use your system module.
Subsequent you may want a module.modulemap file, which is fairly easy.
module ccurl [system] {
header "shim.h"
hyperlink "curl"
export *
}
Concerning the hyperlink property see Xcode launch notes seek for “auto-linking”
Lastly add an additional shim.h header file to import all of the required APIs. Normally I do not wish to import straight the required header information from the modulemap file that is why I’m utilizing this “shim.h” – identify it such as you need – you may see in a second why am I prefering this technique, however here’s a primary one.
#ifndef CLIB_SWIFT_CURL
#outline CLIB_SWIFT_CURL
#import <curl/curl.h>;
#endif
Let’s discuss why I like importing the shim file. When you have platform variations you need to use a neat trick with the assistance of utilizing macros, for instance you may import header information from totally different places in the event you examine for the __APPLE__ platform macro.
#ifndef CLIB_SWIFT_EXAMPLE
#outline CLIB_SWIFT_EXAMPLE
#ifdef __APPLE__
#embody "/usr/native/embody/instance.h"
#else
#embody "/usr/embody/instance.h"
#endif
#endif
Cool, huh? 🍎 + 🔨 = ❤️
[ad_2]
