1

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?

liaogang
  • 508
  • 3
  • 16

1 Answers1

0

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.

Tim Sylvester
  • 22,897
  • 2
  • 80
  • 94