【发布时间】:2021-06-08 03:20:32
【问题描述】:
有谁知道在 C 中创建 WinRT 对象的正确方法是什么?
我正在尝试将使用 WinRT API 的 C++ 代码转换为纯 C 代码。
现在我可以让一些 WinRT 静态函数正常工作。
但是,对于静态函数所需的对象,例如FIAsyncOperation_1_WindowsCDevicesCHumanInterfaceDevice_CHidDeviceVtbl 中的get_Completed 函数的__FIAsyncOperation_1_Windows_CDevicesCEnumerationCDeviceInformation,我找不到创建对象的正确方法。
首先,我在idl文件中找不到这个对象的iid。
其次,我不确定对象的命名空间。
我确实发现了这个类是如何在 C++ 宏中声明的,
#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 */
所以,我在这里尝试使用这个 uuid 和 name_impl 来创建对象,像这样
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);
}
}
构建完成后,程序返回
Couldn't find Windows.Foundation.IAsyncOperation`1<Windows.Devices.Enumeration.DeviceInformation>: -2147221164
由于我没有错误代码映射,我不知道哪个部分出错了。 那么谁能告诉我在c中创建WinRT对象的正确方法?
我在Microsoft forum 中问过这个问题,他们回答他们的问答目前不支持此类问题。 而且我之前也看过this question,但是答案并不能解决我的问题。
更新1: 这是我想从 C++ 转换为 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();
由于 C 中没有 get 函数,我需要创建一个异步对象来处理 C 中的异步操作。我还需要创建一个 IVector 对象来枚举设备的其他属性。
【问题讨论】:
-
这个类是不可创建的。 DeviceInformation 也不是。您可以从 IDeviceInformationStatics::CreateWatcher 开始(如这里所示 docs.microsoft.com/en-us/uwp/api/…)。这是一个类似的 C 代码:pastebin.com/raw/HxAb1P8A
-
@SimonMourier,如果这不是可创建的,那么我应该在需要这个对象的函数中输入什么。由于 WinRT 代码中也有类似的情况,例如用于枚举附加参数的 IVector 对象。如果 C++ 代码有某种结构来创建这个对象,那么在 C 中不应该有一些替代方法吗?
-
系统应该为您提供一个,例如来自 IDeviceInformationStatics::CreateFromIdAsync
-
@SimonMourier,问题是没有这样的功能/我找不到这些对象的这样的功能
-
显示您想要移植到 C 的完整 C++ 部分
标签: c windows-runtime c++-winrt