Это довольно широкий вопрос, поэтому вот несколько ссылок и наблюдений с несколькими примерами.Надеемся, что они полезны.
Пожалуйста, смотрите документацию Apple для UnsafeMutablePointer
struct, а также String
и NSString
:
https://developer.apple.com/documentation/swift/unsafemutablepointer
https://developer.apple.com/documentation/swift/string
https://developer.apple.com/documentation/foundation/nsstring
Еще одно полезное чтение - документы Apple о взаимодействии C и Swift: https://developer.apple.com/documentation/swift/imported_c_and_objective_c_apis
В этом ответе я также опускаю множество аспектов управления памятью, так кака также такие вещи, как отслеживание размера массивов var1
и var2
, поскольку я не знаю особенностей вашей библиотеки.
Что касается фрагмента для инициализации структуры, вы не можетеиспользуйте имя типа в качестве имени переменной, и init
запутает компилятор Swift, потому что он зарезервирован для инициализации именных классов.Давайте назовем переменную myArgs
вместо args
и предположим, что функция инициализации библиотеки C называется initialize
;если это действительно init
, можно легко написать оболочку с другим именем.Другая проблема с фрагментом состоит в том, что myArgs
останется неизменным после инициализации, Ptr
будет фактически инициализирован, поэтому вам придется использовать Ptr
для доступа к инициализированной структуре args
.Таким образом, мы можем опустить Ptr
и использовать неявное мостовое соединение для передачи myArgs
в функцию инициализации.Фрагмент становится
var myArgs = args()
initialize(&myArgs)
Теперь вы можете получить доступ к членам следующим образом:
// Assuming var1 is an array of at least 2 C strings.
// See Swift documentation about optionals on how to deal with
// cases when this assumption breaks down
let s1 = String(cString: myArgs.var1[0]!) // 1st element of var1
let s2 = String(cString: myArgs.var1[1]!) // 2nd element of var1
myArgs.var2.pointee // 1st element of var2
(myArgs.var2 + 1).pointee // 2nd element of var2
let s = String(cString: myArgs.var3) // value of var3
Теперь давайте установим var1 равным {"aa", "bbb"}
:
var var1Buffer =
UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.allocate(capacity: 2)
var var1a : NSString = "aa"
var var1b : NSString = "bbb"
var var1aBuffer = UnsafeMutablePointer<Int8>.allocate(
capacity: var1a.length + 1)
var var1bBuffer = UnsafeMutablePointer<Int8>.allocate(
capacity: var1b.length + 1)
if (var1a.getCString(var1aBuffer, maxLength: var1a.length + 1,
encoding: String.Encoding.utf8.rawValue)
&& var1b.getCString(var1bBuffer, maxLength: var1b.length + 1,
encoding: String.Encoding.utf8.rawValue)) {
var1Buffer[0] = var1aBuffer
var1Buffer[1] = var1bBuffer
myArgs.var1 = var1Buffer
} else { print("Encoding failed...")}
ЗдесьПример установки var2 в виде массива из 5 элементов, равного 200:
var var2Buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 5);
var2Buffer.initialize(repeating: 200, count: 5)
myArgs.var2 = var2Buffer
И установки значения var3:
let newVar3 : NSString = "This is new variable 3"
var var3Buffer = UnsafeMutablePointer<Int8>.allocate(capacity: newVar3.length + 1)
if (newVar3.getCString(var3Buffer, maxLength: newVar3.length + 1, encoding: String.Encoding.utf8.rawValue)) {
myArgs.var3 = var3Buffer
} else { print("Encoding failed...") }
В приведенных выше примерах предполагается кодировка UTF8.