-
Notifications
You must be signed in to change notification settings - Fork 18k
syscall: passing structs by value is problematic on Windows #44020
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
Comments
For functions defined in the syscall or golang.org/x/sys/windows packages we can just make the generated code do the right thing, but I don't see any such functions. Are there any? So I guess the question is: how should we handle functions loaded using It does seem tough to handle that case. I don't see any way to do it. I don't even see how to generalize it, since How many such functions are there? |
Not at the moment in x/sys/windows. There are a few scattered around win32 APIs, though. OLE stuff, for example, passes GUIDs by value rather than by reference. I had to make this change a few months ago: lxn/win@c5100a6#diff-bc58b257cf27988dcfdc566b7e06d2b860735a55a826eccd037b89f5bb5bcda5 There might also be other functions that take structs other than GUIDs, though none I can name off the top of my head. So yea one approach would be making mkwinsyscall split up generic structs according to the splitting rules of the ABI, and then generating helper functions per-arch and using runtime.GOARCH to choose. That would work, though could also be kind of hard. Another approach would be just doing this for matches on I wonder if there's a more clever approach that could be done in syscall.Syscall, though, where arbitrary types can be passed rather than just uintptr. But casting through interface{} sounds kind of bad. Would this need special compiler support? Or more flexible trampolines done in asm that handle this better? Or Go2 generics?
I'm not sure, and this most certainly is not a pressing need of any kind, at least at the moment. But I thought I should at least open the discussion as something to keep in mind as things evolve -- winmd, generics, regabi, maybe other exciting things -- and if anybody has new ideas about it. |
An example of this apparently lives in syscall/, brought to my attention by @rsc's recent CL: https://go-review.googlesource.com/c/go/+/288815 |
Updates: golang/go#36439 Updates: golang/go#44020 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
@gopherbot add OS-Windows |
Perhaps I don't understand the problem. But you should talk to @aclements about it. I reviewed his CL recently that fixed problems passing Go structs / different data types from C to Go during callbacks. Austin needed correct C to Go data translation for future work they do for passing parameters in registers. There is even runtime.TestStdcallAndCDeclCallbacks that uses gcc to build correspondent C dlls to test this interaction. You can add your own data types to see, if they work (for whatever GOARCH). Windows callback code is part of runtime package. But I am sure Go Team can adopt similar code in the compiler. I hope it helps. Alex |
Updates: golang/go#36439 Updates: golang/go#44020 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Updates: golang/go#36439 Updates: golang/go#44020 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Updates: golang/go#36439 Updates: golang/go#44020 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Updates: golang/go#36439 Updates: golang/go#44020 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
On Windows, sometimes GUIDs are passed by value. This amounts to different things on different architectures.
So, here's a function that does not work with mkwinsyscall easily:
//sys setInterfaceDnsSettings(guid windows.GUID, settings *dnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
Currently mkwinsyscall tries to convert guid to uintptr with a cast, which fails, and so the code doesn't compile. Instead I'm doing something pretty gross like this:
That works, I guess. But it's awfully manual. For structs that are larger than a GUID, it's even more annoying. So I was thinking of trying to generalize this somehow.
Where do you suppose that code belongs? In syscall.Syscall? In mkwinsyscall? What should it look like?
CC @alexbrainman @bradfitz @ianlancetaylor @rozmansi
The text was updated successfully, but these errors were encountered: