How to call c function from .dylib file in SPM package swift 5

Hi.. i have .dylib and .h file of c code . i want to call c function in SPM package .i am using xCode for developing SPM package.
Q1. how can i call c function in SPM package ?
Q2. what all method are available to call c function in SPM package ?

In your earlier thread I pointed you to an even earlier thread that has a bunch of helpful info about this. Did you try that approach? If so, where did you get stuck?

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

@eskimo , i am working on that , any other method that is available for importing c function ?

any other method that is available for importing c function ?

Not that I’m aware of.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Hello @eskimo , please may you guide me step by step through the process of above mentioned method . i am creating mac OS cmd project inside that i have created SPM package . In SPM package i want to use c binary file (.dylib , .h) and create some function using c binary file in swift . i want to expose those function of SPM to main file .

There’s two parts to this:

  • Calling a C dynamic library from Swift (A)

  • Doing that in SPM (B)

As I’ve mentioned on an earlier threads, I can’t help with B. However, that thread does have some suggestions from others about how to proceed.

With regards A, I tested this here in my office today using the following steps:

  1. Using Xcode 11.1 GM seed on macOS 10.14.6, I created a new project macOS > App template.

  2. Within that project I created a new target from the macOS > Library template, selecting None (Plain C/C++) in the Framework popup and Dynamic in the Type popup.

  3. In the library target, I created a file from the macOS > C File template, making sure that “Also create a header file” was checked.

  4. In the header I added this code:

     struct WaffleVarnish {
         int glossiness;
         int durability;
     };
     typedef struct WaffleVarnish WaffleVarnish;
    
     extern WaffleVarnish waffleVarnishDoubleDurability(WaffleVarnish existing);
    

    .

  5. In the C file I added this code:

     extern WaffleVarnish waffleVarnishDoubleDurability(WaffleVarnish existing) {
         existing.durability *= 2;
         existing.glossiness /= 2;
         return existing;
     }
    

    .

  6. I built the library target, just to make sure it was working.

  7. I switched to the app target and added a target dependency on the library target.

  8. I then created a Copy Files build phase to copy the library to the Frameworks directory of the app.

  9. Still in the app target, I use the macOS > Cocoa Class template to create an Objective-C class called Hack. This is an easy way to trigger the creation of a bridging header.

  10. I then deleted Hack.h and Hack.m because I don’t need them.

  11. In the bridging header I added this:

    #include "QTestLib.h"
    
    typedef WaffleVarnish (*WaffleVarnishDoubleDurabilityFunctionPointer)(WaffleVarnish existing);
    

    QTestLib.h is the name of the C header from step 3.

  12. I then added the following code to the app:

    let libURL = Bundle.main.bundleURL
        .appendingPathComponent("Contents")
        .appendingPathComponent("Frameworks")
        .appendingPathComponent("libQTestLib.dylib")
    guard let lib = dlopen(libURL.path, RTLD_LAZY) else {
        // … handle error …
        return
    }
    guard let sym = dlsym(lib, "waffleVarnishDoubleDurability") else {
        // … handle error …
        return
    }
    let waffleVarnishDoubleDurability = unsafeBitCast(sym, to: WaffleVarnishDoubleDurabilityFunctionPointer.self)
    let before = WaffleVarnish(glossiness: 32, durability: 10)
    let after = waffleVarnishDoubleDurability(before)
    print(after)
    

    .

  13. When I run this, it prints:

    WaffleVarnish(glossiness: 16, durability: 20)
    

    .

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

3 Likes
Terms of Service

Privacy Policy

Cookie Policy