Does anyone know what is the proper way to create a WinRT object in C?
I'm trying to convert my C++ code that uses WinRT API to plain C code.
And right now I'm able to get a few WinRT static functions working.
However, for the objects required by the static function, like the __FIAsyncOperation_1_Windows_CDevicesCEnumerationCDeviceInformation
for the get_Completed
function in FIAsyncOperation_1_WindowsCDevicesCHumanInterfaceDevice_CHidDeviceVtbl
, I can't find a proper way to create the object.
First, I can't find the iid of this object in the idl file.
Second, I'm not sure about the namespace of the object.
I did find how this class being declare in C++ macro,
#ifndef DEF___FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation_USE
#define DEF___FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation_USE
#if !defined(RO_NO_TEMPLATE_NAME)
namespace ABI { namespace Windows { namespace Foundation {
template <>
struct __declspec(uuid("07faa053-eb2f-5cba-b25b-d9d57be6715f"))
IAsyncOperation<ABI::Windows::Devices::Enumeration::DeviceInformation*> : IAsyncOperation_impl<ABI::Windows::Foundation::Internal::AggregateType<ABI::Windows::Devices::Enumeration::DeviceInformation*, ABI::Windows::Devices::Enumeration::IDeviceInformation*>>
{
static const wchar_t* z_get_rc_name_impl()
{
return L"Windows.Foundation.IAsyncOperation`1<Windows.Devices.Enumeration.DeviceInformation>";
}
};
// Define a typedef for the parameterized interface specialization's mangled name.
// This allows code which uses the mangled name for the parameterized interface to access the
// correct parameterized interface specialization.
typedef IAsyncOperation<ABI::Windows::Devices::Enumeration::DeviceInformation*> __FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation_t;
#define __FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation ABI::Windows::Foundation::__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation_t
/* Foundation */ } /* Windows */ } /* ABI */ }
#endif // !defined(RO_NO_TEMPLATE_NAME)
#endif /* DEF___FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation_USE */
So, I tried to use this uuid and name_impl here to create the object, like this
namespace = L"Windows.Foundation.IAsyncOperation`1<Windows.Devices.Enumeration.DeviceInformation>";
hr = WindowsCreateStringReferenceFunc(namespace, (UINT32)wcslen(namespace), &namespace_string_header, &namespace_string);
static const IID async_iid = { 0x07faa053, 0xeb2f, 0x5cba, { 0xb2, 0x5b, 0xd9, 0xd5, 0x7b, 0xe6, 0x71, 0x5f } };
if (SUCCEEDED(hr)) {
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation* test;
hr = RoGetActivationFactoryFunc(namespace_string, &async_iid, &test);
if (!SUCCEEDED(hr)) {
printf("Couldn't find Windows.Foundation.IAsyncOperation`1<Windows.Devices.Enumeration.DeviceInformation>: %d\n", hr);
}
}
And after the build, the program return
Couldn't find Windows.Foundation.IAsyncOperation`1<Windows.Devices.Enumeration.DeviceInformation>: -2147221164
As I don't have the error code mapping, I don't know which part goes wrong. So can anyone tell me the correct way to create an object of WinRT in c?
I had asked this question in the Microsoft forum and they replied their Q&A currently not support this type of question. And I had also read this question before, but the answer cannot solve my problem.
Update1: This is the code that I want to convert from C++ to C
hstring selector = winrt::to_hstring("System.Devices.InterfaceClassGuid:=\"{4D1E55B2-F16F-11CF-88CB-001111000030}\"") +
winrt::to_hstring(" System.DeviceInterface.Hid.VendorId: = ") + winrt::to_hstring(0x0d28) +
winrt::to_hstring(" AND System.DeviceInterface.Hid.ProductId : = ") + winrt::to_hstring(0x0204);
Windows::Foundation::Collections::IVector<hstring> prop{ winrt::single_threaded_vector<hstring>() };
prop.Append(to_hstring("System.ItemNameDisplay"));
prop.Append(to_hstring("System.Devices.DeviceInstanceId"));
prop.Append(to_hstring("System.Devices.Parent"));
prop.Append(to_hstring("System.Devices.LocationPaths"));
prop.Append(to_hstring("System.Devices.Children"));
prop.Append(to_hstring("System.Devices.DeviceManufacturer"));
DeviceInformationCollection collection = DeviceInformation::FindAllAsync(selector, prop).get();
As there is no get function in C, I would need to create an async object to handle the async operation in C. I also need to create a IVector object to enumerate the additional properties of the devices.