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

0xc0000005 exception when calling static functions #97

Open
jagobagascon opened this issue Aug 19, 2024 · 5 comments
Open

0xc0000005 exception when calling static functions #97

jagobagascon opened this issue Aug 19, 2024 · 5 comments

Comments

@jagobagascon
Copy link
Contributor

          I encountered a similar issue with a very simple test:

https://github.com/balazsgrill/winrt-go/blob/main/storage_test.go

However I doubt that this time it's caused by the GC as it still fails when I disable it

Exception 0xc0000005 0x1 0x50 0x7ffa3fa96d43
PC=0x7ffa3fa96d43

Originally posted by @balazsgrill in #94 (comment)

@jagobagascon
Copy link
Contributor Author

@balazsgrill I did a quick test and it seems that we are not correctly calling static methods.

We are always passing a first NULL parameter:

hr, _, _ := syscall.SyscallN(
	v.VTable().StorageFolderGetFolderFromPathAsync,
	uintptr(0),                    // this is a static func, so there's no this
	uintptr(pathHStr),             // in string
	uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation
)

And even though I can't find anything in the runtime docs related to this (https://learn.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system), it looks like the Rust implementation always passes a pointer to the current parent interface.

So I replaced the first 0 (null) parameter with a pointer to the iStorageFolderStatics instance and it now works:

v := (*iStorageFolderStatics)(unsafe.Pointer(inspectable))
hr, _, _ := syscall.SyscallN(
	v.VTable().StorageFolderGetFolderFromPathAsync,
	uintptr(unsafe.Pointer(v)),    // this is a static func, but we are adding iStorageFolderStatics as "this"
	uintptr(pathHStr),             // in string
	uintptr(unsafe.Pointer(&out)), // out foundation.IAsyncOperation
)

@jagobagascon
Copy link
Contributor Author

Passing NULL or an instance pointer seems to have zero impact on most static methods (Buffer.Create for example works in both cases), but that's not the case for StorageFolder.GetFolderFromPathAsync.

@balazsgrill
Copy link

Thank you for investigating this. It took some time for me to figure out how async operations are working but with this change the test runs successfully
balazsgrill@7cb59d1

balazsgrill added a commit to balazsgrill/winrt-go that referenced this issue Aug 19, 2024
@balazsgrill
Copy link

it looks like the Rust implementation always passes a pointer to the current parent interface.

I suppose then modifying the template to always generate "this" is the appropriate solution (balazsgrill@ed5621d#diff-15f31657e55dbae4403357fb11617c4118c705bf171961ef5d9ae9635fbc2c14)

@jagobagascon
Copy link
Contributor Author

I suppose then modifying the template to always generate "this" is the appropriate solution

Probably. It still bothers me that most of the code just works without adding it. And I cannot find any mention to it in the docs. So I would like to thoroughly test this with the https://github.com/tinygo-org/bluetooth library before adding any PR.

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

No branches or pull requests

2 participants