Problem calling a C function passing a void** from Swift 3


(Lane Schwartz) #1

Hi,

I just moved to Xcode 8 (actually, it upgraded itself without me realizing
it, but anyway), and some previously working Swift 2.2 code now doesn't
work. I'm having trouble migrating.

The code in question is supposed to declare, but not allocate, a block of
memory. A void** to that block of memory was then passed to a C function
(cudaMalloc to be specific) which then allocated memory on the GPU. The
swift 2.2 code that worked was like this:

var data_on_device : UnsafeMutablePointer<Void>

...

self.byteCount = count * sizeof(CFloat)

self.data_on_device = nil

let status = cudaMalloc(&data_on_device, self.byteCount)

Then elsewhere in the code I would convert this pointer to its appropriate
typed version:

UnsafeMutablePointer<Float>(foo.data_on_device)

Can anyone help me get the equivalent functionality in Swift 3?

The closest I've been able to come is the following, which (a) was very
non-obvious and took a lot of trial and error to find, and (b) is ugly.

var data_on_device : UnsafeMutablePointer<Float>

let data_on_device_void_pointer : UnsafeMutableRawPointer
...
self.byteCount = count * MemoryLayout<Float>.size
self.data_on_device = UnsafeMutablePointer<Float>.allocate(capacity:0)
self.data_on_device_void_pointer = UnsafeMutableRawPointer(data_on_device)
var pointer_as_optional : UnsafeMutableRawPointer? =
data_on_device_void_pointer
let pointer : UnsafeMutablePointer<UnsafeMutableRawPointer?> =
UnsafeMutablePointer<UnsafeMutableRawPointer?>(&pointer_as_optional)
let status = cudaMalloc(pointer, self.byteCount)

For reference, the code and git history is here: https://github.com/
dowobeha/mt-marathon-swift-c/blob/master/main.swift

Thanks,
Lane