0
votes

This code worked well in Swift2.3 and now I am converting it to Swift3. So I am getting this error. Anyone has idea, how to fix this?

var cmdLnConf: OpaquePointer?
fileprivate var cArgs: [UnsafeMutablePointer<Int8>]

public init?(args: (String,String)...) {

    // Create [UnsafeMutablePointer<Int8>].
    cArgs = args.flatMap { (name, value) -> [UnsafeMutablePointer<Int8>] in
        //strdup move the strings to the heap and return a UnsageMutablePointer<Int8>
        return [strdup(name),strdup(value)]
    }

    cmdLnConf = cmd_ln_parse_r(nil, ps_args(), CInt(cArgs.count), &cArgs, STrue)

    if cmdLnConf == nil {
        return nil
    }
}

enter image description here

1
Please don't use images in place of code; paste the code into your question.l'L'l
Also, the title of your question gives you the answer...l'L'l
sorry I'm a newbie of swift to c.I have totally no idea how to fix it.Can you help me?Scott.Dong
The error is telling you that instead of [UnsafeMutablePointer<Int8>] it's expecting UnsafeMutablePointer<Int8>, (so without the brackets)...l'L'l
but this is right in swift2.3 and if I delete the brackets there are many other errors appearing- -!Scott.Dong

1 Answers

1
votes

based on our discussion it seems that parameter in your C function should be char *p[]

I made a small test

//
//  f.h
//  test001
//

#ifndef f_h
#define f_h

#include <stdio.h>

void f(char *p[], int len);

#endif /* f_h */

I defined the function with some basic functionality

//
//  f.c
//  test001

#include "f.h"

void f(char *p[], int len) {
    for(int i = 0; i<len; i++) {
        printf("%s\n", p[i]);
    };

};

with the required bridging header

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#include "f.h"

and swift 'command line' application

//
//  main.swift
//  test001
//

import Darwin

var s0 = strdup("alfa")
var s1 = strdup("beta")
var s2 = strdup("gama")
var s3 = strdup("delta")


var arr = [s0,s1,s2,s3]
let ac = Int32(arr.count)


arr.withUnsafeMutableBytes { (p) -> () in
    let pp = p.baseAddress?.assumingMemoryBound(to: UnsafeMutablePointer<Int8>?.self)
    f(pp, ac)
}

it finally prints

alfa
beta
gama
delta
Program ended with exit code: 0

based on the result, your have to use

let count = CInt(cArgs.count)
cArgs.withUnsafeMutableBytes { (p) -> () in
    let pp = p.baseAddress?.assumingMemoryBound(to: UnsafeMutablePointer<Int8>?.self)  
    cmdLnConf = cmd_ln_parse_r(nil, ps_args(), count, pp, STrue)
}

WARNING!!! don't call cArgs.count inside the closure, where the pointer is defined!