Search Unity

Calling C functions from Swift - is it really this difficult??

Discussion in 'iOS and tvOS' started by Gillissie, Dec 28, 2021.

  1. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    The bottom line is that I want to call UnitySendMessage() from Swift code.
    It seems that I have to make a bridge from Swift to C, then call it from the C code.

    I'm going crazy here. I just can't get it to work, despite setting it up based on info I've found scattered around the internet.

    I've created a h and c file with the function I want to access. Here's the full code from those:
    swift2c.h:
    Code (C):
    1. void UnitySendMessageFromSwift(char* msg);
    swift2c.c:
    Code (C):
    1. void UnitySendMessageFromSwift(char* msg)
    2. {
    3.     UnitySendMessage("iOS Message Receiver", "iOSMessageReceived", msg);
    4. }
    5.  
    I've created the "-Bridging-Header.h" file and made sure the "Objective-C Bridging Header" project setting is set to it. That includes the header from the above c file:
    Code (C):
    1. #include "swift2c.h"
    Now to actually use the function, I created a test swift file with this:
    Code (Swift):
    1.  
    2. import Foundation
    3.  
    4. class Something
    5. {
    6.     func doSomething()
    7.     {
    8.         let msg = "Something"
    9.        
    10.         let msg_p = UnsafeMutablePointer<CChar>(mutating: msg)
    11.        
    12.         UnitySendMessageFromSwift(msg_p)
    13.     }
    14. }
    15.  
    Now there's two problems here...
    1. Even though Xcode's IDE shows the UnitySendMessageFromSwift() call as green, it has an error when building: "Cannot find 'UnitySendMessageFromSwift' in scope"
    2. I get a warning when using the UnsafeMutablePointer function, which I don't know how to prevent: "
    Initialization of 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>') results in a dangling pointer". But apparently I can't just pass a String into the function argument. (WHY, APPLE, WHY??)

    I find it very hard to believe this problem hasn't been solved by a lot of Unity developers already, but I can't seem to find anything about it online.

    This article makes it look like magic. https://theswiftdev.com/how-to-call-c-code-from-swift/
     
    aihodge likes this.
  2. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    I guess it's worth noting that I could get this to work on a new project created in Xcode (except not trying to call UnitySendMessage). Not sure why my Unity-generated project is giving this problem.
     
    aihodge likes this.
  3. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    Ok, this seems to be related to the "Target Membership". Unity generates a project with targets for:
    Unity-iPhone
    Unity-iPhone Tests
    UnityFramework

    The plugin files all seem to need to use UnityFramework ONLY. However, if I choose UnityFramework as the Target Membership of the file that has the "Something" class, then it doesn't work. If I change the Target Membership to Unity-iPhone for the file with "Something" class, it doesn't show the error in the code, but shows an error in in the build log for Unity-iPhone:
    Undefined symbol: _UnitySendMessageFromSwift
     
    aihodge likes this.
  4. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    305
    aihodge likes this.