Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

690
Views
Initializing C-struct with const char * in Swift

I have a following C-style struct in the library:

typedef struct ServiceParam
{
    const char *name;
    const char *value;
} ServiceParam;

I'm interested in initializing an array of these structs from Swift, here's what I've tried:

let cHeaders = headers.map{ServiceParam(name: $0.name, value: $0.value)}

But getting the following warning:

Passing 'String' to parameter, but argument 'value' should be a pointer that outlives the call to 'init(name:value:)'

enter image description here

The name and value C-parameters are cast in a form of UnsafePointer<CChar>! and the input type is (name: String, value: String), i.e. Swift-tuple, but I'm flexible with regards to changing the initial type.

So, the whole minimum example looks as follows:

    public func setParams(headers: [(name: String, value: String)] = []) {
        let cHeaders = headers.map{ServiceParam(name: $0.name, value: $0.value)}
        // Do the work with `cHeaders`
    }

What would be the best way to initialize the aforementioned C-style struct from the Swift call site?

The ServiceParam struct is used temporarily only during the parent function call, but the name and value strings are stored as a C++ pairs in an array and their lifetime continues after the function returns:

Later on:

        const auto paramPair = std::make_pair(params->name, params->value);
        instance_variable_array.push_back(paramPair);
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

When passing a Swift string to a C function taking a const char * argument , a temporary C string representation is created automatically. However, that C string is only valid during the function call. That is what happens at

ServiceParam(name: $0.name, value: $0.value)

and causes the warnings. There is a withCString method which can be used to create a C string representation which is valid in some scope:

name.withCString { cName in
    value.withCString { cValue in
        let sp = ServiceParam(name: cName, value: cValue)
        // Do something with sp ...
    }
}

but again, the C string pointers are not valid after execution has left these scopes.

For a longer lifetime of the C strings you can duplicate the memory and release it later:

let cHeaders = headers.map{ ServiceParam(name: strdup($0.name),
                                         value: strdup($0.value)) }

// Do the work with `cHeaders`

for header in cHeaders {
    free(UnsafeMutablePointer(mutating: header.name))
    free(UnsafeMutablePointer(mutating: header.value))
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!