[swift-users] Ugliness bridging Swift String to char *

Kenny Leung kenny_leung at pobox.com
Wed Mar 1 16:23:10 CST 2017


Hi All.

Swift automatically bridges String to char * when calling C functions. For instance, strlen gets translated as:

    public func strlen(_ __s: UnsafePointer<Int8>!) -> UInt

I can call it from Swift like this:

    strlen("|")

I’m But, I’m working with a C struct containing a char *:

    public struct _PQprintOpt {
        public var header: pqbool /* print output field headings and row count */
        public var align: pqbool /* fill align the fields */
        public var fieldSep: UnsafeMutablePointer<Int8>! /* field separator */
        ...
    }
    public typealias PQprintOpt = _PQprintOpt

When I try to assign to fieldSep like this:

    opt.fieldSep = "|"

I get the error:

    Cannot assign value of type 'String' to type 'UnsafeMutablePointer<Int8>!'
    
I assume that the difference is that strlen declares const char * and fieldSep is simply char *, so strlen is non-mutable while fieldSep is mutable. Is this correct?

I currently have this ugly hack to get this to work:

    var opt :PQprintOpt = PQprintOpt()
    guard let fieldSeparator = "|".cString(using: .utf8) else {
        throw Errors.databaseConnectionError("Could not set field separator")
    }
    opt.fieldSep = UnsafeMutablePointer(mutating:fieldSeparator)

Is there a cleaner way this could work, or should this be considered a compiler bug?

Also, why is the conversion to Swift an IUO? NULL is a totally valid value for fieldSep.

Thanks!

-Kenny
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170301/0abea5f8/attachment.html>


More information about the swift-users mailing list