In all of the Swift manual memory management docs and writing I've come across, I've yet to see examples of dealing with C void pointers. I'm attempting to interact with an API nearly identical to C binary search trees — the imported signatures are the same as tsearch
, etc., so I've been testing with with those — but only half successfully.
In plain C, the below creates the tree at root
and places item
within it:
void *root;
tsearch(&item, &root, &compare_method);
The Swift signature for this function is tsearch(UnsafeRawPointer!, UnsafeMutablePointer<UnsafeMutableRawPointer?>!, (UnsafeRawPointer?, UnsafeRawPointer?) -> Int32!)
, and to satisfy all compiler warnings I've called it like so:
var root: OpaquePointer?
withUnsafeMutablePointer(to: &root) {
$0.withMemoryRebound(to: UnsafeMutableRawPointer?.self, capacity: 1) { rootPointer in
let nodePointer = UnsafeMutablePointer<Item>.allocate(capacity: 1)
nodePointer.initialize(to: item)
tsearch(UnsafeRawPointer(nodePointer), rootPointer, tSearchCompareCallback)
}
}
My tSearchCompareCallback
is confirmed as receiving raw pointers that are loading to their types as expected (I've tested with String, structs, objects, you name it, and have added numerous at a time without a problem).
The issue is any further attempts via tfind
or twalk
to access root
, whether as a class property or simply within the same func or block, fail. In taking many approaches, almost all resulting in either "Fatal error: UnsafeMutablePointer.initialize overlapping range" or "EXC_BAD_ACCESS", I'm assuming that despite seemingly being able to populate a search tree I am actually off base with using an OpaquePointer
.
Is there a standard Swift way to call a C function expecting an uninitialized void *
parameter?