Can't get Pointer to Array in Silver

I’m using a C function that expects a pointer to an Array. But somehow, I can’t find a way to pass that pointer over.

Here’s what I’m trying:

import Foundation

let array = [1, 2, 3]

func doSomething(_ data: UnsafePointer<Void>) {
	print("I'm not really doing something.")
}

doSomething(array)

This leads to the following error:

“Parameter 1 is “Swift.Array<Int64!>”, should be “UnsafePointer”, in call to PlayGround.doSomething(_ data: UnsafePointer)”

The same works in Xcode — granted, that’s Swift 4, and I need to replace that pointer type with “UnsafeRawPointer” instead. My guess is that I need to access the array differently in Swift 3 — but I just couldn’t find a way to do this. :frowning:

If anyone has an idea, I’m all ears!
Thanks a lot in advance — any help is appreciated!

Try:

doSomething(&array)

note that array, being a Swift array, will be an Objective-C class (NSArray) under the hood, not a binary array of integers. even if you could cast it to a void pointer, you’d be entering a world of hurt.

Hmmm, okay, I’m afraid my sample seems to have been a little too simplified. Indeed, in this case, the “&” does fix the error (NSArray problems aside), but that didn’t work in my original project.

I’m actually trying to call an OpenGL method; originally declared like this:

void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);

In Swift 4, that becomes

func glBufferData(_ target: GLenum, _ size: GLsizeiptr, _ data: UnsafeRawPointer!, _ usage: GLenum)

In Swift 3, replace “UnsafeRawPointer!” with “UnsafePointer”.

So, in Xcode, I can simply pass an array to that method, and it actually works. Like this:

let indices: [GLubyte] = [ 0, 1, 2, 2, 3, 0 ]
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), sizeOfIndices, indices, GLenum(GL_STATIC_DRAW))

That it works even with that Array could be coincidence, of course. In Apple’s Using Swift with Cocoa and Objective-C, it says, though, that this is allowed; or at least that’s how I understood it (chapter: “Interacting with C APIs” - “Pointers”). That surprised me, too, but who am I to judge. :wink:

So, Marc, you’d recommend to use a Dynamic Array instead, I guess? But still: how to make that call?

I’ve got the full sample here if that helps! Contains sample projects for both Xcode and Fire.

Thanks in advance for any help!

This is the first time for me to use C-APIs from Swift, so I’m quite sure I’m just being stupid. That’s a part that was much more straight-forward in Objective-C. :wink:

Daniel

Yes. if you a dynamic array =, you should be able to pass &myArray[0] as pointer. At least, that works in C# and Oxygene. if you have a fixed array, you can also just pass the array itself

let indices: GLubyte[] = [ 0, 1, 2, 2, 3, 0 ]

Hm, no, I’m still getting an error, unfortunately. I tried:

let indices: GLubyte[] = [ 0, 1, 2, 2, 3, 0 ]
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), sizeOfIndices, &indices[0], GLenum(GL_STATIC_DRAW))

This leads to:
Type mismatch, cannot assign "UnsafePointer<GLubyte>" to "UnsafePointer<GLvoid>"

kinda makes sense? your array is of glbytes, after all. i’m not sure what the right syntax is to cast a pointer to a different target type; carlo will have to answer that in the morning…

as! UnsafePointer<GLvoid>

Ought to do it.

Ah, perfect. That did it, yes! Thanks to both of you! Makes perfect sense.

I think part of my confusion comes from the differences between arrays in Silver and “vanilla” Swift. I’ll try to summarize my current theory about them — could you check if that’s correct?

In vanilla Swift, arrays are value types. It says so here:

In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.

So when I write

let array: [Int] = [1, 2, 3]

I get an NSArray in Silver (a reference type), but I get an “Array” (value type) in vanilla Swift. That’s why it’s possible, in Swift, to pass the pointer to the array created with the above syntax to the OpenGL method, but not in Silver.

[Because if a value is struct (vanilla Arrays are structs), memory alignment should be just like in C.]

Is that correct?

Thanks in advance! :smile:

yep; For interop purposes with Cocoa, our Array type is compatible with objc.

Understood! Thanks. :+1: