2017-06-05 108 views
1

在C文件:在迅速的文件結構C結構斯威夫特

struct CPerson { 
    const char* name; 
    int age; 
}; 

extension UnsafePointer where Pointee == Int8 { 
    var string : String? { 
    return String.init(cString: self) 
    } 
} 

我嘗試使用C結構:

print(CPerson(name: "baby", age: 1).name.string) 
//Optional("baby") 

但:

let p = CPerson(name: "angela", age: 1) 
print(p.name.string , p.age) 
//Optional("") 1 

爲什麼p.name.string ==「」?

我希望p.name.string == 「安吉拉」

感謝。

+0

您是否需要使用C結構(s)?爲什麼不使用Swift實現它? –

回答

1

這是一個內存管理問題。在

let p = CPerson(name: "angela", age: 1) 

你傳遞一個斯威夫特String採取的UnsafePointer<Int8> 參數(的const char *雨燕相當值)的功能。編譯器插入 代碼以創建一個臨時 C字符串表示形式,並且 將其傳遞給CPerson初始化程序。 name字段然後將 指向該臨時C字符串。

問題是當 初始值設定項返回時,此指針不再有效。它可能指向其他的東西,或者可能是一個無效指針 。

A const char *在C中只是一個指針,它並不意味着任何 所有權或內存管理。如果分配

person.name = someString; 

,離開這裏someString定義範圍你可能有完全用C一樣 問題。

所以你必須決定誰負責 分配(和免費)的C字符串存儲。

一種辦法是複製串在斯威夫特和釋放 當不再需要它的內存:

let name = strdup("angela") 

let p = CPerson.init(name: name, age: 1) 
print(p.name.string , p.age) // Optional("angela") 1 

free(name) 

另一種選擇可能是創建C函數CreatePerson()ReleasePerson()其分配和釋放存儲。

+0

謝謝!完美! – Xiuye