0

How can I call the following C function from Swift and what is its swift signature?

int search(const char * const input_words[])

This function expects the C Strings to be in EUC Japanese Encoding, which I already have in the required form. But how do I create an this C array of C string in swift?

I tried adapting the solution suggested in How to pass an array of Swift strings to a C function taking a char ** parameter :

    let args = ["-c", "1.2.3.4", "-p", "8000"]

    // Create [UnsafeMutablePointer<Int8>]:
    var cargs = args.map { strdup($0) }

    search(&cargs) // This gives me "Cannot invoke 'search' 
                   // with an argument list of type '(inout 
                   // Array<UnsafeMutablePointer<Int8>>)'".

Does XCode generates something where I can look it up? I looked in the Derived folder but did not find a thing. I have no idea what the swift signature of the function is and how to call it.

Community
  • 1
  • 1
nrms
  • 81
  • 1
  • 3
  • 3
    Take a look at http://stackoverflow.com/q/29469158/3925941 which also has code for passing in an array of C strings into a C function – Airspeed Velocity Apr 14 '15 at 13:45
  • Why does the compiler just tell me that something in the argument list is wrong, but not what types it is expecting? I would expect that this information is available or at least easy to provide. – nrms Apr 15 '15 at 08:19
  • Option-click the function name to see the definition in Swift (assuming Xcode code completion is working which, sadly, is a big assumption). – Airspeed Velocity Apr 15 '15 at 11:14
  • I did not know that with the option-click function name shows a preview with the function's signature in swift (I just knew command-click to go to the original function definition). I think now can solve this puzzle, thanks a lot! I will post my solution when I am done with it. – nrms Apr 15 '15 at 11:45

1 Answers1

1

I think solved it (with your help). The function signature is:

    func search(input_words: UnsafePointer<UnsafePointer<Int8>>) -> Int32

Now my example code is as follows:

    var args = ["-c", "1.2.3.4", "-p", "8000"]

    // Create [UnsafePointer<Int8>]:
    let cargs: [UnsafePointer<Int8>] = args.map{UnsafePointer<Int8>(strdup($0))}

    search(cargs)

This seems to function as expected. I tested it with the following dummy function:

    int search(const char * const input_words[]){
        int i;
        for (i = 0; i < 10 && input_words[i] != NULL; i++) {
           NSLog(@"word: %s", input_words[i]);
        }
        NSLog(@"i: %i", i);
        return 1;
    }

Which gives me the following sensical output:

2015-04-15 17:02:22.886 example[3492:49189] word: -c
2015-04-15 17:02:22.889 example[3492:49189] word: 1.2.3.4
2015-04-15 17:02:22.889 example[3492:49189] word: -p
2015-04-15 17:02:22.889 example[3492:49189] word: 8000
2015-04-15 17:02:35.904 example[3492:49189] i: 4

If there is a better way, please let me know. Thanks again for the support and advice you gave me. Happy ending.

nrms
  • 81
  • 1
  • 3