5

Others have discussed how to call C code from Swift, and it works nicely. Others have also discussed how calling Swift as a subroutine to C code is a bad idea, because the whole Swift runtime would need to be set up.

But here's my question: if my program is based in Swift, and calls C subroutines, but would like to provide callbacks for those subroutines, is that possible? And could those C subroutines call Swift routines by name, provided that they took C compatible typed parameters (CInt, etc)?

Also, can C and Swift share global variables? In either direction?

Joymaker
  • 813
  • 1
  • 9
  • 23
  • Swift can pass functions as callbacks to C code by using `@convention(c)` http://stackoverflow.com/a/30740730/3141234 – Alexander Apr 28 '17 at 05:11
  • You can pass a global function or a literal closure (which does not capture context) to a C function expecting a function argument. – Martin R Apr 28 '17 at 05:20
  • Possibly helpful: [How to use instance method as callback for function which takes only func or literal closure](http://stackoverflow.com/questions/33260808/how-to-use-instance-method-as-callback-for-function-which-takes-only-func-or-lit). – Martin R Apr 28 '17 at 05:27

1 Answers1

5

The approved way to do this kind of thing is assigning swift functions/closures to C function pointers.

But if you look at the Swift source code, it uses the undocumented @_silgen_name attribute in several places to give swift functions C compatible names, so they can be called directly from C and C++

So this works (tested in XCode 9 beta)

main.c

// declare the function. you would probably put this in a .h
int mySwiftFunc(int);

int main(int argc, const char * argv[]) {

    int retVal = mySwiftFunc(42); // call swift function
    printf("Hello from C: %d", retVal);

    return 0;
}

SomeSwift.swift

@_silgen_name("mySwiftFunc") // give the function a C name
public func mySwiftFunc(number: Int) -> Int
{
    print("Hello from Swift: \(number)")
    return 69
}

But given it's undocumented you probably don't want to use it, and it's a bit murky on what function signatures and parameter types it will work with. ABI stability anyone??

Jon N
  • 1,439
  • 1
  • 18
  • 29
  • Thanks, Jon. I tried both methods and wound up using global swift functions. Mine are big enough that having an entity with a name really helps. Then I keep my big class object (in this case a GameViewController) in a named global variable so that I can explicitly reference any class members And methods I need. – Joymaker Jul 24 '17 at 18:14