问题
I want to call a c++ function in swift
bool getId3Info(const char * filename , char *artist , char * title )
{
// get the file's id3v2 tag, write info back
strcpy(artist,(const char*) id3v2tag->artist().toCString(true));
strcpy(title,id3v2tag->title().toCString(true));
}
So I write a object-c wrapper for this function:
-(bool) getId3Info:(const char * )filename :( const char *)artist :( const char *) title
{
return getId3Info(filename, (char*)artist, (char*)title);
}
So the questions is I can only get the representation of a C string using cStringUsingEncoding
,
can not get the true buffer of a swift String
,
is there another way to do this?
回答1:
In Swift, you can pass a const char*
to a C function like this:
func foo(s: String) { s.withCString({ p in cfunction(p) }) }
or, to be more explicit about the type:
func foo(s: String) { s.withCString({ (p:UnsafePointer<CChar>) in cfunction(p) }) }
(i.e., p is a UnsafePointer<CChar>
, equivalent to const char*
)
If you want to initialize a string from a C function, you need a more complex incantation, something like this:
var buf = Array<CChar>(count: 1000, repeatedValue: 0);
let result = buf.withUnsafeMutableBufferPointer({
(inout ptr: UnsafeMutableBufferPointer<CChar>) -> String? in
cfunction(ptr.baseAddress, ptr.count - 1)
String.fromCString(ptr.baseAddress)
})
Note that the C function must leave the buffer null-terminated. Either it needs to never modify the last byte (thus the ptr.count - 1
, like you would call strncpy
) or it needs to add the null terminator itself (like snprintf
), in which case you can pass in the full buffer size.
来源:https://stackoverflow.com/questions/28084714/a-swift-questions-about-string-and-c-strcpy