How to get return values from pure C function to swift?

前端 未结 1 807
无人共我
无人共我 2021-01-16 19:18

I have a doubt, how to get the returned value from pure c function to swift.

Here my code:

In ViewController.swift // swift file

相关标签:
1条回答
  • 2021-01-16 19:56

    If you want the C function to return a string then the return type should be char * or better const char *:

    // personList.h:
    const char *getPersonName(void);
    
    // personList.c:
    const char *getPersonName(void)
    {
        char *name = "Hello, Swift";
        return name;
    }
    

    This is imported to Swift as

    func getPersonName() -> UnsafePointer<Int8>
    

    and you can create a Swift string from the returned pointer with

    let name = String.fromCString(getPersonName())!
    println(name) // Output: Hello, Swift
    
    // Swift 3:
    let name = String(cString: getPersonName())
    print(name) // Output: Hello, Swift
    

    "Hooray," you'll say, "that's what I need." – But wait!! This works only because "Hello, Swift" in the C function is a string literal. Normally you cannot return a pointer to a local variable from a function, because the memory that the pointer points to may not be valid after return from the function. If the pointer does not point to static memory then you have to duplicate it. Example:

    const char *getPersonName(void)
    {
        char name[200];
        snprintf(name, sizeof name, "%s %s", "Hello", "Swift!");
        return strdup(name);
    }
    

    but now the caller has to deallocate the memory eventually:

    let cstr = getPersonName()
    let name = String.fromCString(cstr)!
    free(UnsafeMutablePointer(cstr))
    
    println(name)
    

    Alternatively, you can change the C function so that the caller passes the memory instead:

    void getPersonName(char *name, size_t nameSize)
    {
        snprintf(name, nameSize, "%s %s", "Hello", "Swift!");
    }
    

    which would be used from Swift as

    var nameBuf = [Int8](count: 200, repeatedValue: 0) // Buffer for C string
    getPersonName(&nameBuf, UInt(nameBuf.count))
    let name = String.fromCString(nameBuf)!
    println(name)
    
    // Swift 3:
    var nameBuf = [Int8](repeating: 0, count: 200) // Buffer for C string
    getPersonName(&nameBuf, nameBuf.count)
    let name = String(cString: nameBuf)
    print(name)
    
    0 讨论(0)
提交回复
热议问题