2015-04-06 14 views
5

Eski bir C terminal uygulamasıyla Swift'ten etkileşime geçmeye çalışıyorum. Kaynak kodunu başarıyla bütünleştirdim ve üstbilgileri C'den Swift'e köprüledim. Kod derler ve Xcode 6.3 beta'dan çalışır. Ben terminali Uygulamanın ana giriş noktası yeniden adlandırdık: YineBir char ** parametresi alarak bir C işlevi için bir dizi Swift dizgisi nasıl geçirilir

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

, bu C işlevine Swift gelen argümanları geçmek mücadele ediyorum. Benim meydan okumam argümanları doğru formatta dönüştürmektir. Ben "cStringUsingEncoding (NSUTF8StringEncoding)" ve "withUnsafePointer" ile karıştırmasını çalıştı, ama hiçbir şans şimdiye kadar ettik

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

: gibi Swift dan tipik giriş görünürdü. Herhangi bir yardım büyük beğeni topluyor!

+0

başlık bahsederek "daha iyi" olabilir Sorun C işlevi çağrısında char ** parametresidir. –

cevap

6

C işlevi

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

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

Bu, olası bir çözüm olarak Swift eşleştirilmiş:

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) } 

Bu gerçeğini kullanır strdup($0) Swift dizge $0 otomatik olarak bir C dizesine dönüştürülür, String value to UnsafePointer<UInt8> function parameter behavior'de açıklandığı gibi .

+0

Teşekkürler, bir çekicilik gibi çalışır. Benzer bir şey yapmaya çalışanlar için, bu C'nin argümanları vektörünü 0 yerine 0'dan başlayarak eklemeliyim. Argümanlarımı güncelledim: args = ["", "-c", "1.2.3.4", " -p "," 8000 "]. – Mark

+0

Eğer bir komut satırı oyunum varsa, bunu çalıştırmak ve argümanları ona aktarabiliyor ve stdout'unu bir metin alanına aktarabiliyor musunuz? Ya da herşeyi kendi işlevini kullanarak yapmak zorunda mıyım? @Mark – MasterWizard

+0

@AhmedNassar: Bildiğim kadarıyla iOS'ta harici programları çalıştıramazsınız. –

0
Martin'in cevabı üzerine

Bina, kendinizi, sen String.withCString benzer tarzda bir fonksiyonu haline dup/serbest bölümünü sarabilirdiniz bu yapıyoruz bulursanız:

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) 
} 
İlgili konular