Howto: Using WinRT apis from Island/Windows


(RemObjects) #21

bugs://80062 got closed with status fixed.

(Benoît Bousquet) #22

Thanks Carlo.

I won’t be back in the office until Monday but I’ll check tomorrow’s build for sure.


(Benoît Bousquet) #23

I have tested this and it seems your fixes have enabled me to get a little further.

I am getting another ‘silent’ crash on a line that shouldn’t crash, however:

func GetGattService(serviceUuid: RemObjects.Elements.System.Guid) -> GattDeviceService? {
	var service: UnsafePointer<__x_ABI_CWindows_CDevices_CBluetooth_CGenericAttributeProfile_CIGattDeviceService>
	guard (*(*object).lpVtbl).GetGattService(object, serviceUuid, &service) == S_OK else {
		return nil
	return GattDeviceService(object: service)

The silent crash occurs on the first line of the function (the var service line)…

(Carlo Kok) #24

That usually means it went wrong before that; how do I see this? (I figure I need a bluetooth id but will just any do?) The last bug was a compiler bug, something was cdecl isntead of stdcall.

(Benoît Bousquet) #25

You need a valid Bluetooth LE identifier and a valid service ID for that device. That wouldn’t be too practical on your end. Is it possible this is just a failure with the Guid parsing call? It gets optimized out by the debugger so I can’t really tell you if it parsed properly.

The calling code was the following:

public static let DeviceInformationService = "0000180a-0000-1000-8000-00805f9b34fb"
if let deviceInformationService = device.GetGattService(serviceUuid: RemObjects.Elements.System.Guid.Parse(DeviceInformationService)) {
	// ...

(Benoît Bousquet) #26

If I change the GettGattService function so it doesn’t do anything (aside from returning nil), I don’t get the silent crash:

func GetGattService(serviceUuid: RemObjects.Elements.System.Guid) -> GattDeviceService? {
	var service: UnsafePointer<__x_ABI_CWindows_CDevices_CBluetooth_CGenericAttributeProfile_CIGattDeviceService>
	return nil
	//guard (*(*object).lpVtbl).GetGattService(object, serviceUuid, &service) == S_OK else {
		//return nil
	//return GattDeviceService(object: service)

The issue seems to be the guard line.

EDIT: Actually, scratch that. I was misusing the AddRef method and assumed its return value was a pointer to the object (it’s actually a reference count). I’ll fix my code and see how it behaves afterwards.

EDIT 2: I am getting a 0x80004002 HRESULT from GetGattService. Suspecting something is afoul with the Guid to GUID cast. Will investigate after lunch.

(Carlo Kok) #27

Either way I’m going to look at the “lost exceptions”, I didn’t notice that last time I tested your testcase.

(Carlo Kok) #28

Any update from your end? (Will investigate after lunch.)

(joseasl) #29

Could this be of any helpful for Island?

(Benoît Bousquet) #30

Apologies. My spouse’s mother passed away Monday night and I missed work. I have also been stuck with a pinched nerve for over a week, which has affected my arm and made typing quite painful. Things are improving slowly and I should be able to check things out this PM at the office (power outage this AM).

(Carlo Kok) #31

My condolences, sorry to hear that. No rush, I was just making sure that we weren’t both waiting for eachothers feedback.

(Benoît Bousquet) #32

Thank you.

We just got power back at the office and I checked the return code:

GetGattService returns 0x80070490 (-2147023728)
The only match I found for this error code is E_PROP_ID_UNSUPPORTED in vfwmsgs.h

This is puzzling.

EDIT: I’m wondering why the 2nd param to GetGattService presents itself as a straight up GUID, as opposed to other related functions who show it as an UnsafePointer.

(marc hoffman) #33

just FYI, carlo is off until monday due to holidays, so he might not be able to get back to you until then.

(Carlo Kok) #34

I think I know what’s going on here:

            __RPC__in __x_ABI_CWindows_CDevices_CBluetooth_CIBluetoothLEDevice * This,
            /* [in] */ GUID serviceUuid,
            /* [out][retval] */ __RPC__deref_out_opt __x_ABI_CWindows_CDevices_CBluetooth_CGenericAttributeProfile_CIGattDeviceService **service);

Note how GUID is in, but really should be passed by ref. I’ll see what I can do there on the compiler end.

(Carlo Kok) #35

was bugs://80165: pass struct by val on island/win32/i386

fixed for the next build.