Report this app

Description

[ad_1]

Interacting with C libraries from the Swift language is absolutely superb, from this publish can be taught probably the most of C interoperability.

Swift

From Swift 4 there’s native assist for wrapping C libraries in Swift system module packages. This implies that you could eaily ship your personal system modules, you simply must discover ways to use the Swift Bundle 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 concerning 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 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

#embrace <stdio.h>

lengthy factorial(int n);

#endif /* factorial_h */

That is gona be the implementation of the strategy (factorial.c):

#embrace "factorial.h"

lengthy factorial(int n)  n == 1) return 1;
    return n * factorial(n-1);

Contained in the bridging header, merely import the C header file:

#embrace "factorial.h"

Someplace inside a Swift file you should utilize the factorial methodology:

print("Good day (factorial(5))!")

Compile and run. ๐Ÿ”จ It simply works. ๐ŸŒŸ Magic! ๐ŸŒŸ

You are able to do the very same factor to make use of Goal-C lessons inside your Swift tasks. Apple has nice docs about this method, it is best to learn that if you wish to know extra about combine and match.


Delivery C code with SPM

The actual enjoyable begins once you begin utilizing the Swift Bundle Supervisor to construct C household based mostly sources. From Swift 3.0 you possibly can construct C language targets with SPM. If you do not know the way to use the SPM software, it is best to learn my complete tutorial concerning the Swift Bundle Supervisor first.

The one factor that you will must do it is 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 little thing what it’s good to construct the factorial instance with SPM.



import PackageDescription

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

The listing construction must be one thing like this.

Sources
    factorial
        embrace
            factorial.h
        factorial.c

You also needs to change the #embrace "factorial.h" line contained in the factorial.c file to #embrace "embrace/factorial.h" as a result of we made a brand new embrace listing. That is NOT essential, however in case you do not put your umbrella header into the embrace listing, you may want to offer a modulemap file, and supply the right location of your header. If you happen to use the embrace construction SPM will generate every little thing for you.

With this method you possibly can import your cfactorial module from some other Swift package deal and name the factorial methodology, like we did via Xcode. You simply have so as to add this module as a dependency, oh by the best way you possibly can even name this module from one other C undertaking made with SPM! ๐Ÿ’ฅ

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

Congratulations, you simply shipped your first C code with Swift Bundle Supervisor. Please try the instance repository, you possibly can construct and run the undertaking 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 possibly can crete a model new wrapper package deal with the assistance of the Swift Bundle Supervisor. To start out you should utilize the swift package deal init --type system-module command, it will create a generic template undertaking.

These are particular packages in keeping with Apple, you simply must ship your personal modulemap and a header file to reveal the wanted APIs, however first – clearly – you may want the same old package deal definition file:



import PackageDescription

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

Contained in the Bundle.swift file you possibly can 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 package deal header recordsdata with the assistance of the pkgConfig property. For instance if you wish to use libxml2 and pkg-config isn’t 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 simple.

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

In regards to 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 prefer to import straight the required header recordsdata 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 methodology, however here’s a fundamental 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 possibly can import header recordsdata from completely different places in case you examine for the __APPLE__ platform macro.

#ifndef CLIB_SWIFT_EXAMPLE
#outline CLIB_SWIFT_EXAMPLE

#ifdef __APPLE__
    #embrace "/usr/native/embrace/instance.h"
#else
    #embrace "/usr/embrace/instance.h"
#endif

#endif

Cool, huh? ๐ŸŽ + ๐Ÿ”จ = โค๏ธ

[ad_2]

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.