Find out how to name C code from Swift


From Swift 4 there may be native assist for wrapping C libraries in Swift system module packages. This implies which you could simply ship your personal system modules, you simply should study how you can use the Swift Package deal Supervisor.😅

Bridging header inside Xcode

Let’s hearth up Xcode and begin a model new single view app iOS undertaking. 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 hard, as a result of it additionally helps different C household languages, 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 should utilize the factorial methodology:

print("Hey (factorial(5))!")
// it really prints out "Hey 120!" ;)

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 system, you need to learn that if you wish to know extra about combine and match.

Transport C code with SPM

The actual enjoyable begins once you begin utilizing the Swift Package deal Supervisor to construct C household based mostly sources. From Swift 3.0 you’ll be able to construct C language targets with SPM. If you do not know how you can use the SPM software, you need to learn my complete tutorial in regards to the Swift Package deal Supervisor first.

The one factor that you will have to do it is a correct listing construction (plus you will want the bundle description file), and the bundle supervisor will take care all the remainder. Right here is the whole lot what you must construct the factorial instance with SPM.



import PackageDescription

let bundle = Package deal(
    identify: "cfactorial",
    merchandise: [
        .library(name: "cfactorial", targets: ["cfactorial"]),
    ],
    targets: [
        .target(
            name: "cfactorial",
            path: "./Sources/factorial"
        ),
    ]
)

The listing construction ought to be one thing like this.

Sources
    factorial
        embody
            factorial.h
        factorial.c

You also needs to 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 essential, however if you happen to do not put your umbrella header into the embody listing, you will want to offer a modulemap file, and supply the proper location of your header. In case you use the embody construction SPM will generate the whole lot for you.

With this system you’ll be able to import your cfactorial module from some other Swift bundle and name the factorial methodology, like we did by Xcode. You simply have so as to add this module as a dependency, oh by the way in which you’ll be able to even name this module from one other C undertaking made with SPM! 💥

.bundle(url: "https://gitlab.com/theswiftdev/cfactorial", .department("grasp")),

Congratulations, you simply shipped your first C code with Swift Package deal Supervisor. 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 immediately from Swift you’ll be able to crete a model new wrapper bundle with the assistance of the Swift Package deal Supervisor. To begin you should utilize the swift bundle init --type system-module command, this can create a generic template undertaking.

These are particular packages based on Apple, you simply should ship your personal modulemap and a header file to reveal the wanted APIs, however first – clearly – you will want the same old bundle definition file:



import PackageDescription

let bundle = Package deal(
    identify: "ccurl",
    suppliers: [
        .brew(["curl"]),
        .apt(["libcurl4-openssl-dev"])
    ]
)

Contained in the Package deal.swift file you’ll be able to set the suppliers for the library (like brew on macOS or aptitude for Ubuntu / Debian and the others). Right here is an effective recommendation for you: sudo apt-get set up pkg-config below Linux to make issues work, as a result of the system will seek for bundle header recordsdata with the assistance of the pkgConfig property. For instance if you wish to use libxml2 and pkg-config just isn’t put in, you will not have the ability to compile / use your system module.

Subsequent you will want a module.modulemap file, which is fairly simple.

module ccurl [system] {
    header "shim.h"
    hyperlink "curl"
    export *
}

In regards to the hyperlink property see the Xcode launch notes seek for “auto-linking”

Lastly add an additional shim.h header file to import all of the required APIs. Often I do not prefer to import immediately the required header recordsdata from the modulemap file that is why I’m utilizing this shim.h – identify it such as you need – you will see in a second why am I preferring this methodology, however here’s a primary one.

#ifndef CLIB_SWIFT_CURL
#outline CLIB_SWIFT_CURL

#import <curl/curl.h>;

#endif

Let’s speak about why I like importing the shim file. When you have platform variations you should utilize a neat trick with the assistance of utilizing macros, for instance you’ll be able to import header recordsdata from totally different areas if you happen to 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? 🍎 + 🔨 = ❤️

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles