2016-04-22 7 views
0

Iトラブル署名の交流機能のためのアレイにスイフト文字列の配列を変換した午前:スウィフト、CONSTチャー*のCONSTで配列* CONST *

PGconn *PQconnectStartParams(const char * const *keywords, const char * const *values, int expand_dbname) 

*次のように機能することを「オプション」と呼ばれ、フィード:[文字列]:だから私は辞書の内容を変換しよう

<UnsafePointer<UnsafePointer<Int8>> 

:としてが現れ

var keys = [[Int8]]() 
var values = [[Int8]]() 
for (key, value) in options { 
    var int8Array = key.cStringUsingEncoding(NSUTF8StringEncoding)! 
    keys.append(int8Array) 
    int8Array = value.cStringUsingEncoding(NSUTF8StringEncoding)! 
      values.append(int8Array) 
} 
pgConnection = PQconnectStartParams(UnsafePointer(keys), UnsafePointer(values), 0) 

コンパイルして実行しますが、機能しません。

洞察力があれば幸いです。

+0

を行うことによって、適切なC互換のポインタを取得することができます:あなたが話しています'PQconnectdbParams()'という名前の関数はまだ 'PQconnectStartParams()'という名前の関数を呼び出しています...? – RastaJedi

+0

'const char * const * keywords'を見てください。 'keywords'は' const char'への 'const'ポインタへのポインタです(これは' char const'と同じです、両方とも "定数文字"を意味します)。これは、単一の文字列( "nullで終了する文字配列")を探しているわけではないが、文字列の*配列*を探している可能性が高いことを意味します。 'char ** argv'のようなものです。私はSwiftについてはあまりよく分かりませんが、Swift文字列をCのNULL終端文字配列に変換する方法を理解してから、それらの配列をC配列に変換する方法を見つける必要があります文字列、私は思う。 – RastaJedi

+0

申し訳ありません。事務的エラードキュメントの間違った部分を見ていた。関数のシグネチャを修正しました。あなたは正しいです。ヌル終端配列を探しているわけではありません。私は弦の必要と配列。私は自分のコードで生成していると思っていたものです。 – user5892643

答えて

3

これは完璧ではありませんが、少なくとも動作します。

let options = ["key1": "value1", "key2": "value2", "key3": "value3", "key4": "value4"] 

var keys = [String]() 

for (key, value) in options { 

    keys.append(key) 
} 

//you need to identify how many paramenters should be provided and set them following "static way" 
//I did not find how to prepare this dynamically 
let cKey1 = keys[0].cStringUsingEncoding(String.defaultCStringEncoding())! 
let key1Pointer = UnsafePointer<CChar>(cKey1) 

let cKey2 = keys[1].cStringUsingEncoding(String.defaultCStringEncoding())! 
let key2Pointer = UnsafePointer<CChar>(cKey2) 

let cKey3 = keys[2].cStringUsingEncoding(String.defaultCStringEncoding())! 
let key3Pointer = UnsafePointer<CChar>(cKey3) 

let cKey4 = keys[3].cStringUsingEncoding(String.defaultCStringEncoding())! 
let key4Pointer = UnsafePointer<CChar>(cKey4) 


let keysCArray = [key1Pointer, key2Pointer, key3Pointer, key4Pointer] 

f(keysCArray) 

/* 
C - code 

void f(const char * const *keywords) { 

printf("%s\n", keywords[0]); 
printf("%s\n", keywords[1]); 
printf("%s\n", keywords[2]); 
printf("%s\n", keywords[3]); 

} 
*/ 

希望します。あなたが望むなら私はサンプルアプリケーションを共有することができます。ここで

+1

Thanks Melifaro。私はすでに質問を投稿する前にこのアプローチを試していましたが、EXC_BAD_ACCESSを得続けました。だから私はそのアプローチが間違っていると思った。しかし、どのくらいの数のパラメータを使って配列をnullに終わらせる必要があるかを特定することについてのあなたの意見は、そこで、UnsafePointer (nil)を各配列に追加しました。すべて動作します。私の電球をオンにしてくれてありがとう! – user5892643

+1

素敵な発見!フィードバックありがとうございます。 –

0

は、一般的にそれを行いますSwift3のArrayの拡張機能です:

public extension Array { 

    // Translate [String] to (const char * const *), which translates to Swift as 
    public func cStringArray() throws -> ArrayBridge<Element,CChar> { 
     return try ArrayBridge<Element,CChar>(array:self) { 
      guard let item = $0 as? String, 
        let translated = item.cString(using: .utf8) else { 
       fatalError() 
      } 
      return translated 
     } 
    } 
} 

/* 
We need to have this intermediate object around to hold on to the translated objects, otherwise they will go away. 
The UnsafePointer won't hold on to the objects that it's pointing to. 
*/ 
public struct ArrayBridge<SwiftType,CType> { 

    let originals :[SwiftType] 
    let translated :[[CType]] 
    let pointers :[UnsafePointer<CType>?] 
    public let pointer :UnsafePointer<UnsafePointer<CType>?> 

    init(array :[SwiftType], transform: @noescape (SwiftType) throws -> [CType]) throws { 
     self.originals = array 
     self.translated = try array.map(transform) 

     var pointers = [UnsafePointer<CType>?]() 
     for item in translated { 
      pointers.append(UnsafePointer<CType>(item)) 
     } 
     pointers.append(nil) 
     self.pointers = pointers 
     self.pointer = UnsafePointer(self.pointers) 
    } 
} 

その後すぐに[OK]を

try stringArray.cStringArray().pointer 
関連する問題