I want to call some AboutDialogProtocol methods like set(artists:) and set(authors:) Both methods have declared a parameter of the type UnsafeMutablePointer<UnsafePointer<gchar>?>! but I currently cannot call them from Swift.
On the GTK C API documentation those parameters appear as NULL-terminated array of strings (That is a pointer to an array of pointers to char, where the last element is a NULL pointer):
If I call the method with an array of Strings, it doesn't compile:
about.set(artists: [
"Catalog Icons from Twemoji",
"Desktop Icons from <a href='https://icons8.com/'>Icons8</a>",
"Other Icons by Jesús Abelardo Saldívar Aguilar"
])
error: cannot convert value of type '[String]' to expected argument type 'UnsafeMutablePointer<UnsafePointer<gchar>?>?' (aka 'Optional<UnsafeMutablePointer<Optional<UnsafePointer<Int8>>>>')
about.set(artists: [
^
I have tried a snippet from Swift Forums for similar situations (Converting a Swift Array of Strings to a C Array of Strings) with minor modifications, but haven't been successful. The code compiles, but crashes on run time,
possibly because the last element of the array is not null/nil (In the online example, the Vulkan API does not require the last element to be NULL):
extension Collection {
/// Creates an UnsafeMutableBufferPointer with enough space to hold the elements of self.
public func unsafeCopy() -> UnsafeMutableBufferPointer<Self.Element> {
let copy = UnsafeMutableBufferPointer<Self.Element>.allocate(capacity: self.count)
_ = copy.initialize(from: self)
return copy
}
}
extension String {
/// Create UnsafeMutableBufferPointer holding a null-terminated UTF8 copy of the string
public func unsafeUTF8Copy() -> UnsafeMutableBufferPointer<gchar> { self.utf8CString.unsafeCopy() }
}
...
let about = AboutDialog();
let artistsCredits = [
"Iconos del catálogo por <a href='https://github.com/twitter/twemoji'>Twemoji</a>",
"Otros iconos por Jesús Abelardo Saldívar Aguilar",
"Iconos de escritorio por <a href='https://icons8.com/'>Icons8</a>"
].map({ UnsafePointer($0.unsafeUTF8Copy().baseAddress) }).unsafeCopy().baseAddress
about.set(artists: artistsCredits)
'swift run ChickenPOS' terminated by signal SIGSEGV (Address boundary error)
I haven't yet figured how to add a nil last element.
I think SwiftGtk functions or methods accepting UnsafeMutablePointer<UnsafePointer<gchar>?>! as a parameter sould instead accept an array of strings [String] to make them easier to use.
I'm currently running this on Fedora 40 aarch64, Swift 5.8.1
I want to call some
AboutDialogProtocol
methods likeset(artists:)
andset(authors:)
Both methods have declared a parameter of the typeUnsafeMutablePointer<UnsafePointer<gchar>?>!
but I currently cannot call them from Swift.On the GTK C API documentation those parameters appear as NULL-terminated array of strings (That is a pointer to an array of pointers to char, where the last element is a NULL pointer):
If I call the method with an array of Strings, it doesn't compile:
I have tried a snippet from Swift Forums for similar situations (Converting a Swift Array of Strings to a C Array of Strings) with minor modifications, but haven't been successful. The code compiles, but crashes on run time, possibly because the last element of the array is not null/nil (In the online example, the Vulkan API does not require the last element to be NULL):
https://forums.swift.org/t/create-c-string-array-from-swift/31149/2
I haven't yet figured how to add a nil last element.
I think SwiftGtk functions or methods accepting
UnsafeMutablePointer<UnsafePointer<gchar>?>!
as a parameter sould instead accept an array of strings[String]
to make them easier to use.I'm currently running this on Fedora 40 aarch64, Swift 5.8.1