0

I have an UnsafeMutablePointer<Character> filled by a CoreFoundation method.

If I NSLog it with %s placeholder, it outputs just fine.

But if I try with Swift's print it just writes the memory address.

Tried nearly everything... also I don't understand why if I try to access the underlying memory property I get a EXC_BAD_ACCESS.

let deviceName = UnsafeMutablePointer<Character>.alloc(64)

/* other statements in which deviceName is filled */

NSLog("device %s by %s", deviceName, manufacturerName)
// Outputs correctly the string

print(String(deviceName[0]))
// Get an EXC_BAD_ACCESS error at runtime

print(String(deviceName.memory))
// Get an EXC_BAD_ACCESS error at runtime

let str = withUnsafePointer(&deviceName) { String.fromCString(UnsafePointer($0)) }
print(str)
// Outputs an empty string

print("\(deviceName) by \(manufacturerName)")
// Outputs just memory addresses
Teejay
  • 7,210
  • 10
  • 45
  • 76
  • Could you show a little more of your code, please? What's in this pointer, what are you doing, what result are you after, and what happens when you try? – matt Oct 19 '15 at 01:39
  • So may I assume that it is in fact a C string? – matt Oct 19 '15 at 01:46
  • @matt Yes, `deviceName` is in fact a C NUL-terminated char array – Teejay Oct 19 '15 at 01:47
  • And you've tried `print(deviceName[0])` and you don't get the first letter? That makes me think you don't really have this C string after all. You couldn't show how you got hold of it? – matt Oct 19 '15 at 01:51
  • I would expect a C string to be an UnsafePointer. I don't see how it could be an UnsafePointer. – matt Oct 19 '15 at 01:53
  • I think we've established that you're not willing to show your actual code. It is crucial to know why you think this would be an UnsafePointer and how you populated it, but you seem not to want to reveal that. Plus, this is a very odd way to get hold of a C string in Swift. Why won't you show where this device name _really_ comes from? – matt Oct 19 '15 at 01:56
  • Maybe there's another error in my code, but the thing I know is that NSLog success in logging that string! – Teejay Oct 19 '15 at 01:56
  • I can show all the code, it's not a secret, it's just a bit long. The string is the name of an Audio device installed on the current machine. – Teejay Oct 19 '15 at 01:57
  • But that is because NSLog ignores how you incorrectly typed `deviceName` to start with. It just looks at the contents of memory. But Swift can't do that. – matt Oct 19 '15 at 01:57
  • `AudioObjectGetPropertyData(deviceIDs[idx], &deviceAddress, 0, nil, &propertySize, deviceName)` is the line that fills the deviceName – Teejay Oct 19 '15 at 01:58

1 Answers1

0

You seem unwilling to show your code, so I can't really help. But this looks just wrong:

let deviceName = UnsafeMutablePointer<Character>.alloc(64)
/* other statements in which deviceName is filled */

That is not how to get hold of a C string in Swift, and if you believe that it is a C string in Swift, you're wrong; it would need to be an array of Int8 (C characters), not Swift Character (a struct!), to be a C string.

In other words, C char (your question's title) is not Swift Character - they are nothing like one another. A C char is a small number, a Swift Character is an object in an object-oriented language that C knows nothing about!

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Please read in the comment above. If you want I can copy the entire code, it's just a bit long. I reported the line that fills the array. – Teejay Oct 19 '15 at 01:59
  • I've told you what you need to know. I don't know what AudioObjectGetPropertyData does but no way in the world would it provide a C array of Swift Character. – matt Oct 19 '15 at 02:02
  • Ok, now I tried with Int8, and printing `deviceName[0]` results in 66 that is ascii-code for uppercase B, for "Built-in Microphone" – Teejay Oct 19 '15 at 02:04
  • For future references, this code will generate the Swift string: `String.fromCString(deviceName)!` – Teejay Oct 19 '15 at 02:07
  • Thanks for your help! – Teejay Oct 19 '15 at 02:09