Open hu13 opened 2 weeks ago
We've worked with buffers and vectors, but always as readers, we never had to deal with creating an iterable.
And it seems that there is no specific class in Windows.Foundation.Collections
that implements the IIterable
interface. So the only solution I can think of is to provide your own implementation.
I will try to look into it, but I'll have to find some free time to do so because I think this is going to be quite complex to do.
In the meantime you can check how the delegates do this by defining their own functions VTable
using syscall.NewCallback
.
@jagobagascon thanks. i will take a look at delegates.go
I wanted to help a little bit more so I made a quick test that seems to be working. I've uploaded it as a gist: https://gist.github.com/jagobagascon/fd807800ee5c658955a81f0dd1c40bb8
You should be able to run it after generating the iterable and iterator structs.
It's far from perfect and required quite a bit of black magic to make it work:
func moveNext(inst, out unsafe.Pointer) uintptr {
offset := unsafe.Offsetof(collectionsIterator{}.IIterator)
// good old C pointer magic tricks
it := (*collectionsIterator)(unsafe.Pointer(uintptr(inst) - offset))
it.index++
return getHasCurrent(inst, out)
}
I hope this helps.
[!NOTE] I don't think we will have time to work on this in the short term, so PRs are welcome 😉
@jagobagascon i truly appreciate your help. I will test it out asap.
@jagobagascon i think the gist is missing the iunknown's RegisterInstance() logics. could you share that please?
i have tried this
var (
ole32 = syscall.NewLazyDLL("ole32.dll")
procCoRegisterClassObject = ole32.NewProc("CoRegisterClassObject")
)
// RegisterInstance registers the COM class object with the system
func RegisterInstance(clsid *ole.GUID, obj interface{}) (unk *ole.IUnknown, err error) {
ret, _, err := procCoRegisterClassObject.Call(
uintptr(unsafe.Pointer(clsid)),
uintptr(unsafe.Pointer(&obj)),
// uintptr(context),
// uintptr(flags),
uintptr(unsafe.Pointer(&unk)),
)
if ret != 0 {
err = ole.NewError(ret)
}
return
}
// Initialize all properties: the malloc may contain garbage
iid := ole.NewGUID(winrt.ParameterizedInstanceGUID(GUIDIIterable, itemSignature))
// create type instance
size := unsafe.Sizeof(*(*arrayIterable)(nil))
instPtr := kernel32.Malloc(size)
inst := (*arrayIterable)(instPtr)
callbacks, err := RegisterInstance(iid, inst)
if err != nil {
panic(err)
}
but it is not quite correct yet. I got
--- FAIL: Test_GetCurrent (0.00s)
panic: The parameter is incorrect. [recovered]
panic: The parameter is incorrect.
I got it working now at least with your test of int iterable.
i need to use // get the callbacks for the VTable callbacks := delegate.RegisterCallbacks(instPtr, inst)
and also implement Invoke() for the Iterator and Iterable struct we registered.
i ran into invalid memory access issues when i try to set it up for StorageProviderItemProperty
. If possible, could you take a look at this gist https://gist.github.com/hu13/4ce6e6f9019ff5c448071998128dac79 that contains what my set up?
You are right, sorry. I refactored the delegates and extracted the code shared among all structs to the iunknown
package. That way you won't need to implement Invoke
(which is only required by delegates).
I pushed the changes to this branch: https://github.com/saltosystems/winrt-go/tree/feature/slice-iterable-testing-prototype
With them the main.go
added to the Gist should work as expected.
This branch is working for the any
type and the number of items returned from getMany
is also correct. Did you change any logics from the gist?
I fixed the item assignment using reflection: https://gist.github.com/jagobagascon/fd807800ee5c658955a81f0dd1c40bb8#file-array-go-L356
hi there.
i am trying to use this api https://learn.microsoft.com/en-us/uwp/api/windows.storage.provider.storageprovideritemproperties.setasync?view=winrt-26100#windows-storage-provider-storageprovideritemproperties-setasync(windows-storage-istorageitem-windows-foundation-collections-iiterable((windows-storage-provider-storageprovideritemproperty)))
and it requires initializing a list of. I looked at the interfaces that go generate came up for
StorageProviderItemProperty
that implements Iterablebut i can't seem to see a pattern on how to generate a
Iterable<StorageProviderItemProperty>
from that. I am wondering if you have any experience interacting with Iterable interface from winrt-go before and can provide some insight. Thanks.apologize if this is a bit off topics.