2016-09-23 29 views
0

私はNSArray<NSString*>*オブジェクトを持っており、文字列の配列をchar**として取り込むC APIを呼び出す必要があります。CStringの配列にNSStringの配列を変換するには?

これを行うにはどうすればよいですか?重要な注意点は、c-文字列がconst修飾子を持つことはできませんので、以下のようなものがUTF8String戻りconst char*ので、十分ではない:あなたが頼ることができないとしてあなたには、いくつかの動的メモリをしたいだろう

NSArray<NSString*>* names = ...; 
int len = args.count; 
char* cNames[len]; 
for(int i = 0; i < len; i++) { 
    cNames[i] = names[i].UTF8String; 
}; 
+0

C APIは文字列の内容を変更しますか? – kennytm

+0

私はそう信じませんが、理論的にはそうすることができます。 – zeroimpl

+1

もしそうなら、元のNSArrayを変更するものはありません。上記は基本的に正しいアプローチです。面倒な 'malloc'と' strncpy'を追加して完全なコピーを作成したいだけです。答えは上記とCの2つです。 –

答えて

1

UTF8Stringのバッキングメモリが解放されます。

NSArray *strings = @[ @"String 1", @"Other string", @"Random String"]; 
char **cStrings = NULL; 
NSInteger numCStrings = strings.count; 

if (numCStrings) { 
    cStrings = (char **)calloc(numCStrings, sizeof(char*)) ; 

    if (cStrings) { 
     // Safer to allocate memory for each string 

     for (NSInteger i=0;i<numCStrings;i++) { 
      NSString *nsString = strings[i]; 
      char *cString = (char *)malloc([nsString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1); // + 1 for \0 

      if (cString) { 
       strcpy(cString, nsString.UTF8String); 
       cStrings[i] = cString; 
      } else { 
       // You should handle your error 
      } 
     } 
    } else { 
     // You should handle your error 
    } 
} 

for (NSInteger i=0;i<numCStrings;i++) { 
    NSLog(@"C-String (%ld): %s", i, cStrings[i]); 
} 

// Note you need to free your memory later! 
// Do any additional setup after loading the view, typically from a nib. 
for (NSInteger i=0;i<numCStrings;i++) { 
    if (cStrings[i]) { 
     // Free each string 
     free(cStrings[i]); 
    } 
} 

// Free the array 
free(cStrings); 

cStrings = NULL; 
numCStrings = 0; 
+0

ありがとうございます。醜いが、私はそれがする必要がありますね! – zeroimpl

+0

1つのマイナーな修正 - 'nsString.length'は、UTF-16エンコーディングの長さを返します。 '[nsString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]'を使う必要があります – zeroimpl

関連する問題