Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I pass NSPoint to a method? #88

Closed
hajimehoshi opened this issue Jan 7, 2023 · 14 comments
Closed

How can I pass NSPoint to a method? #88

hajimehoshi opened this issue Jan 7, 2023 · 14 comments
Labels
enhancement New feature or request

Comments

@hajimehoshi
Copy link
Member

https://developer.apple.com/documentation/appkit/nscursor/1524612-initwithimage

Currently, passing a struct via Send is not supported, right?

@TotallyGamerJet
Copy link
Collaborator

This is correct. struct arguments are not supported by Send since they aren't supported by RegisterLibFunc

@hajimehoshi
Copy link
Member Author

For NSPoint, would passing X and Y as adjacent arguments work?

@TotallyGamerJet
Copy link
Collaborator

For the case of NSPoint that should work on amd64 (see this). As well as on amd64 (see Sec. B - 3). Ignore the fact that is a Microsoft page. Windows arm64 uses the same calling convention as macOS.

Godbolt shows the same thing.

Note though that doing so is flaky for anything unaligned or bigger than 16 bytes. The reason I had not added support yet is because you have to determine if it is passed in registers or as a pointer to the struct.

@hajimehoshi
Copy link
Member Author

Thanks!

At the same time, RegisterFunc doesn't support returning structs yet. I read the implementation of cursorPosition but this was quite tricky...

@anhoder
Copy link

anhoder commented Apr 5, 2023

Is there any new progress on this?
I've encountered the same issue and I'm attempting to retrieve currentTime of AVPlayer.

@TotallyGamerJet
Copy link
Collaborator

TotallyGamerJet commented Apr 5, 2023

There is a work around by using NSInvocation. That's what ebitengine does. However, it doesn't work on normal C functions that take or return structs. It only works on Objective-C methods

@anhoder
Copy link

anhoder commented Apr 6, 2023

Thanks. It looks like what I want

@ksil
Copy link

ksil commented Jun 21, 2023

Hello! This is a wonderful project. I just wanted to follow up on this thread regarding passing/returning structs, as I have a huge interest in calling functions that accept/return POD types (at least on linux and darwin). This would enable us to interface with some standard libraries we use without having to rewrite them from scratch in golang.

Has there been any progress on this front, or is there a branch I can check out?

@TotallyGamerJet
Copy link
Collaborator

No there hasn't been any work. If you are interested in tackling this a PR would be much appreciated.

As for solutions on macOS you can use NSInvocation as was mentioned earlier. Another cross platform solution is libffi. I personally haven't used it but it should work to circumvent the lack of struct support in purego.

@ksil
Copy link

ksil commented Jun 22, 2023

Appreciate the fast response! Libffi is a neat idea. A fast alternative may also be to write wrapper functions that only use raw pointers as arguments, but, of course, that somewhat circumvents a proper solution to this struct-passing problem...

@TotallyGamerJet
Copy link
Collaborator

Wrappers are another good solution. Of course adding support for structs would be the best.

@TotallyGamerJet
Copy link
Collaborator

For anyone looking for an example of NSInvocation here’s one that opens a window. https://go.dev/play/p/J7nKrpnG1CH

@JupiterRider
Copy link
Contributor

@TotallyGamerJet @ksil
Structures work on linux if the size not bigger then 64 bits.
If you pass them as argument, convert them into a uintptr like so:

clearBackground(*(*uintptr)(unsafe.Pointer(&color.RGBA{255, 255, 255, 255})))

If the function returns a struct bigger then 64 bits, pass a reference as first argument:

var texture Texture2D
loadTexture(uintptr(unsafe.Pointer(&texture)), "icon.png")

@TotallyGamerJet
Copy link
Collaborator

Sure that works for some cases but wouldn't everywhere especially arm64 where a struct with all the same field types that's less than or equal to 8 bytes is put into one register in reverse order.

I'm currently working on proper struct support. Arm64 is looking pretty solid. My plan is to have it done by end of next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants