/ / C文字列ポインタとしてchar(char *ではなく)をすばやく読み取る-swift、osc

Cの文字列ポインタとしてswift reading char(char *ではない) - swift、osc

今週はSwift、特にSwift 4から始めたばかりで、ブリッジヘッダーを介してCライブラリを使用しています。 liblo、ネットワークソケットを介したOSC(Open Sound Control)形式のメッセージの送受信を処理します。

サーバースレッドを開始し、OSCを受信できますCコールバック-> Swiftクロージャを介してメッセージを送信し、Swiftで数値引数値を適切に読み取ります。しかし、文字列値の読み取りで問題が発生しています。

libloメッセージの引数タイプ lo_argは、和集合のCtypedefです。 文字列引数タイプは、Int8としてSwiftにマップされる単純な文字として宣言されます。

Cでは、次の方法で文字列を取得できます。 &argv[i]->s コールバックから lo_arg **argv アレイ。 libloを使用したObj-Cプロジェクトでは、次のものを使用します。

// get string value of first argument
lo_arg arg = argv[0];
NSString *s = [NSString stringWithUTF8String:&arg->s];
// do something with s

Swiftでは、Int8のアドレスを取得して、それをStringにフィードしようとしましたが、これは機能しますが、最初の文字のみを取得します。

// get string value of first argument
if var arg : lo_arg = argv?.pointee![0] {
withUnsafePointer(to: &arg.s) {
let s = String(cString: $0)
// so something with s
}
}

私は何か間違ったことをしていますか?これらは同等だと思いますが、合格です $0strlen() アラ print("strlen: (strlen($0)") 「1」の長さのみを印刷します。 複数文字の文字列が実際にSwift以外のテストプログラムで送信されていることを確認しました。Swiftが文字列がC文字列のヘッドアドレスではなく単一文字であると想定しているのか、さらに必要なのか疑問に思っています。ポインタ変換。

回答:

回答№1は0

少し掘り下げた後、Swiftが切り捨てていることを確認できます lo_arg->s そして、 lo_arg->S 私の64ビットシステムでは8バイトまでの文字列値 sizeof(char)。これは、来るlo_argから文字列を読み取ろうとしたときに発生します Swiftから。同じ値を読む Cで 正常に動作するため、Swiftは1文字分のスペースからの読み取りのみを予約/許可しているようです。 lo_argをSwiftからCに転送し、 printf() 最大8文字の切り捨てられた文字列も表示されます。

簡単な解決策は、文字列を読み取らないようにすることですSwiftによって生成されたlo_argから、Cの生のlo_messageからlo_argを取得し、char「pointer」をconst char *にキャストします。Swiftは可変長の文字列として理解します。ブリッジヘッダーに追加した実用的なユーティリティ関数は次のとおりです。

/// return an lo_message argv[i]->s in a format Swift can understand as a String
const char* lo_message_get_string(lo_message message, int at) {
return (const char *)&lo_message_get_argv(message)[at]->s;
}

/// return an lo_message argv[i]->S in a format Swift can understand as a String
const char* lo_message_get_symbol(lo_message message, int at) {
return (const char *)&lo_message_get_argv(message)[at]->S;
}

Swiftでは、文字列に変換できます。

let s = String(cString: lo_message_get_string(msg, 0))
// do something with s