2015-04-06 8 views
5

लेते हुए एक सी फ़ंक्शन में स्विफ्ट स्ट्रिंग्स की एक सरणी कैसे पास करें I स्विफ्ट से पुराने सी टर्मिनल ऐप से बातचीत करने का प्रयास कर रहा हूं। मैंने स्रोत कोड को सफलतापूर्वक एकीकृत किया है और हेडर को सी से स्विफ्ट में ब्रिज किया है। कोड संकलन और एक्सकोड 6.3 बीटा से चलाता है। मैं करने के लिए टर्मिनल एप्लिकेशन के मुख्य प्रवेश बिंदु नाम दिया गया है:चार सी पैरामीटर

int initialize(int argc, char **argv); 

फिर भी, मैं इस सी कार्य करने के लिए स्विफ्ट से तर्क पारित करने के लिए संघर्ष कर रहा हूँ। मेरी चुनौती तर्क को सही प्रारूप में परिवर्तित करना है। स्विफ्ट से ठेठ इनपुट देखने की तरह होगा:

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

मैं "cStringUsingEncoding (NSUTF8StringEncoding)" और "withUnsafePointer" के साथ खिलवाड़ की कोशिश की है, लेकिन कोई किस्मत अब तक। कोई भी मदद बहुत ही सराहनीय होगी!

+0

शीर्षक उल्लेख करते हुए "बेहतर" हो सकता है कि सी फंक्शन कॉल में समस्या char ** पैरामीटर है। –

उत्तर

6

सी समारोह

int initialize(int argc, char **argv); 

रूप

func initialize(argc: Int32, argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>) -> Int32 

यह एक संभव समाधान है स्विफ्ट को मैप किया है:

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

// Create [UnsafeMutablePointer<Int8>]: 
var cargs = args.map { strdup($0) } 
// Call C function: 
let result = initialize(Int32(args.count), &cargs) 
// Free the duplicated strings: 
for ptr in cargs { free(ptr) } 

यह इस तथ्य का उपयोग करता है strdup($0) स्विफ्ट स्ट्रिंग में $0 स्वचालित रूप से एक सी स्ट्रिंग में परिवर्तित हो जाता है, जैसा कि String value to UnsafePointer<UInt8> function parameter behavior में बताया गया है।

+0

धन्यवाद, एक आकर्षण की तरह काम करता है। दूसरों के लिए कुछ ऐसा करने की कोशिश करने के लिए, मुझे यह जोड़ना चाहिए कि सी 0 के बजाय इंडेक्स 1 से शुरू होने वाले तर्क वेक्टर को पास करता है। मैंने अपने तर्क अपडेट किए: args = ["", "-c", "1.2.3.4", " -पी "," 8000 "]। – Mark

+0

यदि मेरे पास कमांड लाइन गेम है, तो क्या आपको लगता है कि इसे चलाने और इसे तर्क देने के लिए संभव है, और इसके स्टडआउट को टेक्स्ट एरिया में निकालें उदाहरण के लिए स्विफ्ट में? या क्या मुझे अपने काम का उपयोग करके पूरी तरह से खेल करना है? @ मार्क – MasterWizard

+0

@ अहमदनासर: जहां तक ​​मुझे पता है, आप आईओएस में बाहरी कार्यक्रम नहीं चला सकते हैं। –

0
मार्टिन जवाब पर

बिल्डिंग, आप अपने आप को यह एक बहुत कुछ कर, आप String.withCString लिए एक समान शैली में एक समारोह में dup/मुक्त हिस्सा लपेट सकता है पाते हैं:

import Darwin 

func withCStrings 
    <R, S: SequenceType where S.Generator.Element == String> 
    (strings: S, @noescape body: (UnsafeBufferPointer<UnsafeMutablePointer<Int8>>) -> R) 
    -> R { 

    let cstrings = map(strings) { strdup($0) } + [nil] 

    let result = cstrings.withUnsafeBufferPointer(body) 

    for ptr in cstrings { free(ptr) } 

    return result 
} 

let execvargs = ["/usr/bin/say"] + dropFirst(Process.arguments) 

let execvresult = withCStrings(execvargs) { 
    execv($0[0], $0.baseAddress) 
} 
संबंधित मुद्दे