在 C 中创建 WinRT 对象的正确方法
Proper way to create a WinRT object in C
有谁知道在 C 中创建 WinRT 对象的正确方法是什么?
我正在尝试将使用 WinRT API 的 C++ 代码转换为纯 C 代码。
现在我可以让一些 WinRT 静态函数正常工作。
但是对于静态函数需要的对象,比如__FIAsyncOperation_1_Windows_CDevicesCEnumerationCDeviceInformation
对于FIAsyncOperation_1_WindowsCDevicesCHumanInterfaceDevice_CHidDeviceVtbl
中的get_Completed
函数,我找不到合适的方法来创建对象。
首先,我在idl文件中找不到这个对象的iid。
其次,我不确定对象的命名空间。
我确实发现了这个 class 是如何在 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);
}
}
构建之后,程序 return
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 对象来枚举设备的附加属性。
好的,在 a GitHub repo 的一些调查和评论的一些帮助之后,我找到了问题的答案。
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation
这样的对象实际上没有 contrustor 函数
我需要做的是实现 vtbl 结构中列出的功能。
例如,当我想要一个 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection
的对象时,我将需要实现 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl
中列出的函数,即
typedef struct __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl
{
BEGIN_INTERFACE
HRESULT (STDMETHODCALLTYPE* QueryInterface)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
REFIID riid,
void** ppvObject);
ULONG (STDMETHODCALLTYPE* AddRef)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This);
ULONG (STDMETHODCALLTYPE* Release)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This);
HRESULT (STDMETHODCALLTYPE* Invoke)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* asyncInfo,
AsyncStatus asyncStatus);
END_INTERFACE
} __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl;
所以我应该有这样的东西
static HRESULT STDMETHODCALLTYPE async_query_interface(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
REFIID riid,
void** ppvObject)
{
if (!ppvObject) {
return E_INVALIDARG;
}
*ppvObject = NULL;
static const IID async_iid = { 0x4a458732, 0x527e, 0x5c73, { 0x9a, 0x68, 0xa7, 0x3d, 0xa3, 0x70, 0xf7, 0x82 } };
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &async_iid)) {
*ppvObject = This;
This->lpVtbl->AddRef(This);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE async_add_ref(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This)
{
return 1;
}
static ULONG STDMETHODCALLTYPE async_release(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This)
{
return 1;
}
static HRESULT STDMETHODCALLTYPE async_invoke(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* asyncInfo,
AsyncStatus asyncStatus)
{
//The callback when the async complete or have some problem
}
而这里的iidstatic const IID async_iid = { 0x4a458732, 0x527e, 0x5c73, { 0x9a, 0x68, 0xa7, 0x3d, 0xa3, 0x70, 0xf7, 0x82 } };
可以在winrt文件夹下的头文件中找到(windows.devices.enumeration.h),
namespace ABI { namespace Windows { namespace Foundation {
template <>
struct __declspec(uuid("4a458732-527e-5c73-9a68-a73da370f782"))
IAsyncOperationCompletedHandler<ABI::Windows::Devices::Enumeration::DeviceInformationCollection*> : IAsyncOperationCompletedHandler_impl<ABI::Windows::Foundation::Internal::AggregateType<ABI::Windows::Devices::Enumeration::DeviceInformationCollection*, __FIVectorView_1_Windows__CDevices__CEnumeration__CDeviceInformation*>>
{
static const wchar_t* z_get_rc_name_impl()
{
return L"Windows.Foundation.AsyncOperationCompletedHandler`1<Windows.Devices.Enumeration.DeviceInformationCollection>";
}
};
当所有这些都准备好后,我只需要这样做就可以得到 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection
对象
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection async_op;
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl async_vtbl = {
.QueryInterface = async_query_interface,
.AddRef = async_add_ref,
.Release = async_release,
.Invoke = async_invoke,
};
async_op.lpVtbl = &async_vtbl;
hr = async_dev_collection->lpVtbl->put_Completed(async_dev_collection, &async_op);
我找到答案的example,就是用这个方法创建了一个__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController
对象,有兴趣或者不明白的可以看看我的答案。
基本上,我已经创建了一个小型基础架构,如此 sample 中所示,用于使用纯 C 使用 UWP。
要实现您自己的处理程序,您需要几个步骤。
首先声明您的 object 结构 - 您可以使用一个 object 实现多个接口。不要忘记为结束标记添加 space。
struct bthgenhandler {
struct stdifaceopts;
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CBluetoothDevice;
struct stdiftrailer;
char* markend;
};
对于简单的界面,您可以将结构嵌入其中(如果您使用的是 MSVC)。
第二次初始化您的接口 vtable 及其实现的内容(而第二次您将需要一个额外的终止元素):
static __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CBluetoothDeviceVtbl bthfromaddrhandlervtbl = { QueryInterface, AddRef, Release, bthgetRfcommsrvcsInvoke };
static const IID* bthgetRfcommsrvcsimplements[] = { &IID_IUnknown, &IID___FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult, 0 };
3rd 创建您的实际 object - 您也可以使用 malloc
- 如果您决定嵌入任何数据(在 markend
之后 - 设置 shouldbefreed
和您的初始 object 数到 0
以便您的 object 自动释放):
static struct bthgenhandler bthgetRfcommsrvcshandler = { .lpVtbl = &bthfromaddrhandlervtbl, bthgetRfcommsrvcsimplements, 1, &bthgetRfcommsrvcshandler, };
4th 使用任何 object 接口 vtbls 调用需要回调 object 的方法(QueryInterface
无论如何都会找到正确的接口 - 目前我们在这个例子中只有 1 个):
__FIAsyncOperation_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult_put_Completed(asyncop, &bthgetRfcommsrvcshandler.lpVtbl);
现在对于 IIDS - 我想到的是一个单独的 header,我从 header 的 C++ 部分将 UIID 复制为字符串(例如:)
GEN_IID_FROM_STRING("522c25d1-866b-5de4-bd8e-1feb5ae60d47", __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult)
其中 "522c25d1-866b-5de4-bd8e-1feb5ae60d47"
来自 windows.devices.bluetooth.h
。
最后,为了激活 object,您有两个助手 - activateclassdirect
和 activateclasslight
- 有时如果第一个不起作用,请尝试另一个。
有谁知道在 C 中创建 WinRT 对象的正确方法是什么?
我正在尝试将使用 WinRT API 的 C++ 代码转换为纯 C 代码。
现在我可以让一些 WinRT 静态函数正常工作。
但是对于静态函数需要的对象,比如__FIAsyncOperation_1_Windows_CDevicesCEnumerationCDeviceInformation
对于FIAsyncOperation_1_WindowsCDevicesCHumanInterfaceDevice_CHidDeviceVtbl
中的get_Completed
函数,我找不到合适的方法来创建对象。
首先,我在idl文件中找不到这个对象的iid。
其次,我不确定对象的命名空间。
我确实发现了这个 class 是如何在 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);
}
}
构建之后,程序 return
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 对象来枚举设备的附加属性。
好的,在 a GitHub repo 的一些调查和评论的一些帮助之后,我找到了问题的答案。
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformation
这样的对象实际上没有 contrustor 函数
我需要做的是实现 vtbl 结构中列出的功能。
例如,当我想要一个 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection
的对象时,我将需要实现 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl
中列出的函数,即
typedef struct __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl
{
BEGIN_INTERFACE
HRESULT (STDMETHODCALLTYPE* QueryInterface)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
REFIID riid,
void** ppvObject);
ULONG (STDMETHODCALLTYPE* AddRef)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This);
ULONG (STDMETHODCALLTYPE* Release)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This);
HRESULT (STDMETHODCALLTYPE* Invoke)(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* asyncInfo,
AsyncStatus asyncStatus);
END_INTERFACE
} __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl;
所以我应该有这样的东西
static HRESULT STDMETHODCALLTYPE async_query_interface(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
REFIID riid,
void** ppvObject)
{
if (!ppvObject) {
return E_INVALIDARG;
}
*ppvObject = NULL;
static const IID async_iid = { 0x4a458732, 0x527e, 0x5c73, { 0x9a, 0x68, 0xa7, 0x3d, 0xa3, 0x70, 0xf7, 0x82 } };
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &async_iid)) {
*ppvObject = This;
This->lpVtbl->AddRef(This);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE async_add_ref(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This)
{
return 1;
}
static ULONG STDMETHODCALLTYPE async_release(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This)
{
return 1;
}
static HRESULT STDMETHODCALLTYPE async_invoke(__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* This,
__FIAsyncOperation_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection* asyncInfo,
AsyncStatus asyncStatus)
{
//The callback when the async complete or have some problem
}
而这里的iidstatic const IID async_iid = { 0x4a458732, 0x527e, 0x5c73, { 0x9a, 0x68, 0xa7, 0x3d, 0xa3, 0x70, 0xf7, 0x82 } };
可以在winrt文件夹下的头文件中找到(windows.devices.enumeration.h),
namespace ABI { namespace Windows { namespace Foundation {
template <>
struct __declspec(uuid("4a458732-527e-5c73-9a68-a73da370f782"))
IAsyncOperationCompletedHandler<ABI::Windows::Devices::Enumeration::DeviceInformationCollection*> : IAsyncOperationCompletedHandler_impl<ABI::Windows::Foundation::Internal::AggregateType<ABI::Windows::Devices::Enumeration::DeviceInformationCollection*, __FIVectorView_1_Windows__CDevices__CEnumeration__CDeviceInformation*>>
{
static const wchar_t* z_get_rc_name_impl()
{
return L"Windows.Foundation.AsyncOperationCompletedHandler`1<Windows.Devices.Enumeration.DeviceInformationCollection>";
}
};
当所有这些都准备好后,我只需要这样做就可以得到 __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection
对象
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollection async_op;
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CEnumeration__CDeviceInformationCollectionVtbl async_vtbl = {
.QueryInterface = async_query_interface,
.AddRef = async_add_ref,
.Release = async_release,
.Invoke = async_invoke,
};
async_op.lpVtbl = &async_vtbl;
hr = async_dev_collection->lpVtbl->put_Completed(async_dev_collection, &async_op);
我找到答案的example,就是用这个方法创建了一个__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController
对象,有兴趣或者不明白的可以看看我的答案。
基本上,我已经创建了一个小型基础架构,如此 sample 中所示,用于使用纯 C 使用 UWP。
要实现您自己的处理程序,您需要几个步骤。
首先声明您的 object 结构 - 您可以使用一个 object 实现多个接口。不要忘记为结束标记添加 space。
struct bthgenhandler {
struct stdifaceopts;
__FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CBluetoothDevice;
struct stdiftrailer;
char* markend;
};
对于简单的界面,您可以将结构嵌入其中(如果您使用的是 MSVC)。
第二次初始化您的接口 vtable 及其实现的内容(而第二次您将需要一个额外的终止元素):
static __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CBluetoothDeviceVtbl bthfromaddrhandlervtbl = { QueryInterface, AddRef, Release, bthgetRfcommsrvcsInvoke };
static const IID* bthgetRfcommsrvcsimplements[] = { &IID_IUnknown, &IID___FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult, 0 };
3rd 创建您的实际 object - 您也可以使用 malloc
- 如果您决定嵌入任何数据(在 markend
之后 - 设置 shouldbefreed
和您的初始 object 数到 0
以便您的 object 自动释放):
static struct bthgenhandler bthgetRfcommsrvcshandler = { .lpVtbl = &bthfromaddrhandlervtbl, bthgetRfcommsrvcsimplements, 1, &bthgetRfcommsrvcshandler, };
4th 使用任何 object 接口 vtbls 调用需要回调 object 的方法(QueryInterface
无论如何都会找到正确的接口 - 目前我们在这个例子中只有 1 个):
__FIAsyncOperation_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult_put_Completed(asyncop, &bthgetRfcommsrvcshandler.lpVtbl);
现在对于 IIDS - 我想到的是一个单独的 header,我从 header 的 C++ 部分将 UIID 复制为字符串(例如:)
GEN_IID_FROM_STRING("522c25d1-866b-5de4-bd8e-1feb5ae60d47", __FIAsyncOperationCompletedHandler_1_Windows__CDevices__CBluetooth__CRfcomm__CRfcommDeviceServicesResult)
其中 "522c25d1-866b-5de4-bd8e-1feb5ae60d47"
来自 windows.devices.bluetooth.h
。
最后,为了激活 object,您有两个助手 - activateclassdirect
和 activateclasslight
- 有时如果第一个不起作用,请尝试另一个。