語境
從 Swift,我試圖呼叫libxlsxwriterC 庫的特定函式。檔案在這里:https ://libxlsxwriter.github.io/worksheet_8h.html#a62bf44845ce9dcc505bf228999db5afa
該函陣列裝一個“豐富的字串”(相??當于 AttributedString,其中不同的格式/樣式適用于不同的范圍)并將其寫入 Excel 作業表中的特定單元格。在 C 中,該函式的作業方式如下:
lxw_format *bold = workbook_add_format(workbook);
format_set_bold(bold);
lxw_format *italic = workbook_add_format(workbook);
format_set_italic(italic);
lxw_rich_string_tuple fragment11 = {.format = NULL, .string = "This is " };
lxw_rich_string_tuple fragment12 = {.format = bold, .string = "bold" };
lxw_rich_string_tuple fragment13 = {.format = NULL, .string = " and this is "};
lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic" };
lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
&fragment13, &fragment14, NULL};
worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
問題
我有一個lxw_rich_string_tuple結構陣列,但我不清楚如何將其轉換為worksheet_write_rich_string()接受的指標陣列:
// The worksheet object and `lxw_format` objects are already existent.
// This array contains multiple well-formed `lxw_rich_string_tuple` structs, which I can see in the debugger.
//
var rawTuples: [lxw_rich_string_tuple] = ...
// Parameters:
// - the worksheet on which to write this string
// - the row of the cell in which to write
// - the column of the cell in which to write
// - a null-terminated array of pointers to `lxw_rich_string_tuple` structs
// - an optional format object to use, null in this case.
//
worksheet_write_rich_string(worksheet, 0, 1, ?, NULL);
麻煩的是?。我已經嘗試了各種方法withUnsafeBytes,withUnsafeMutableBytes但UnsafeMutableRawPointer().bindMemory(to:capacity:)我無法弄清楚神奇的 Swift 胡言亂語來做 C 語言中如此簡單的事情。謝謝。
我的嘗試
這不會產生編譯器錯誤,但會因訪問錯誤例外而崩潰:
let argsSize: Int = rawTuples.count
rawTuples.withUnsafeMutableBufferPointer { rawTuplesPointer in
let ptr = UnsafeMutableRawPointer(rawTuplesPointer.baseAddress!).bindMemory(to: lxw_rich_string_tuple.self, capacity: argsSize)
var tuplePointers: [UnsafeMutablePointer<lxw_rich_string_tuple>?] = []
for i in 0 ..< argsSize
{
let tp: UnsafeMutablePointer<lxw_rich_string_tuple>? = ptr (i * MemoryLayout<lxw_rich_string_tuple>.stride)
tuplePointers.append(tp)
}
tuplePointers.append(nil)
tuplePointers.withUnsafeBufferPointer { tpPointer in
let m = UnsafeMutablePointer(mutating: tpPointer.baseAddress)
worksheet_write_rich_string(lxw_worksheet, cell.row, cell.col, m, nil)
}
}
uj5u.com熱心網友回復:
嘗試這個:
rawTuples.withUnsafeMutableBufferPointer { p in
guard let arrBaseAddress = p.baseAddress else { return }
var pointersToEachArrayElement: [UnsafeMutablePointer<_>?] =
Array(arrBaseAddress ..< arrBaseAddress.advanced(by: p.count))
pointersToEachArrayElement.append(nil)
pointersToEachArrayElement.withUnsafeMutableBufferPointer { q in
// use q.baseAddress in the call to worksheet_write_rich_string
}
}
這個想法類似于您的嘗試 - 創建一個指向每個陣列元素的指標陣列。但與您的嘗試不同,我避免呼叫指標型別的初始化程式(我認為您不應該這樣做),而是盡可能withXXX多地使用這些函式。
您還應該考慮只圍繞 C 函式和lxw_rich_string_tuple. 有時 C 函式只是沒有以一種非常方便的方式橋接到 Swift ,不幸的是,這不是我第一次經歷這樣的事情:(
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/506503.html
