0

There's a ton of references to this question but none of them seem to work. I'm using Xcode 14.1. What am I doing wrong?

I have a C buffer in a struct:

struct MY_C_STRUCT
{
    char buff[256];   //Contains null-terminated C-string in UTF-8 encoding
};

and I have a Swift struct where I'm trying to set its variable from MY_C_STRUCT::buff:

class MyStruct : ObservableObject
{
    @Published public var Buff : String = ""

    func from_MY_C_STRUCT(mi : MY_C_STRUCT)
    {
         Buff = String(cString: mi.buff)
    }
}

That gives me on the String(cString:) line:

No exact matches in call to initializer

4
  • Check this: stackoverflow.com/q/27455773/1187415 Commented Dec 4, 2022 at 15:08
  • Further info at this blog: oleb.net/blog/2017/12/… Commented Dec 4, 2022 at 16:09
  • @MartinR there are like 5 suggestions there. I tried all of them and all gave me errors. Commented Dec 4, 2022 at 20:14
  • What errors? The code in stackoverflow.com/a/27456220/1187415 (with record.name replaced by mi.buff, of course) compiles without problems in my test. Commented Dec 4, 2022 at 20:30

1 Answer 1

1

As this blog explains, Swift imports fixed-sized C arrays as tuples!

One way to treat the tuple as a buffer is to use withUnsafeBytes to get a pointer to the memory and then pass that pointer to String(cString:):

Replace:

Buff = String(cString: mi.buff)

with:

Buff = withUnsafeBytes(of: mi.buff) { (rawPtr) -> String in
    let ptr = rawPtr.baseAddress!.assumingMemoryBound(to: CChar.self)
    return String(cString: ptr)
}
Sign up to request clarification or add additional context in comments.

2 Comments

I'm getting Cannot pass immutable value as inout argument: 'mi' is a 'let' constant for that
@c00000fd: Replace &mi.buff by mi.buff

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.