简体   繁体   中英

C Struct to Swift

in c file : have a struct

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

in swift file:

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

I try use c struct:

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

but :

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

why p.name.string == "" ?

I hope that p.name.string == "angela"

thanks.

It is a memory management problem. In

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

you pass a Swift String to a function taking an UnsafePointer<Int8> argument (the Swift equivalent of const char * ). The compiler inserts code to create a temporary C string representation and passes that to the CPerson initializer. The name field then points to that temporary C string.

The problem is that this pointer is no longer valid when the initializer returns. It may point to something else or may be an invalid pointer.

A const char * in C is just a pointer, it does not imply any ownership or memory management. You would have exactly the same problem in C if you assign

person.name = someString;

and leave the scope where someString is defined.

So you have to decide who is responsible to allocate (and free) the C string storage.

One option would be to duplicate the string in Swift and release the memory when it is no longer needed:

let name = strdup("angela")

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

free(name)

Another option might be to create C functions CreatePerson() and ReleasePerson() which allocate and release the storage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM