如何在 Rust winapi 编程中使用 COM VARIANT? [英] How to use a COM VARIANT in Rust winapi programming?
问题描述
我正在尝试转换 C++ COM 代码 将 TaskScheduler
转为 Rust 并坚持使用 ITaskService::Connect
的 VARIANT
参数:
I'm trying to convert the C++ COM code for TaskScheduler
to Rust and am stuck with the VARIANT
argument of ITaskService::Connect
:
extern crate winapi;
use winapi::{
ctypes::c_void,
shared::{
guiddef::{GUID, REFCLSID, REFIID},
ntdef::{HRESULT, NULL},
rpcdce::{RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE},
winerror::FAILED,
wtypes::VARENUM,
wtypesbase::CLSCTX_INPROC_SERVER,
},
um::{
combaseapi::{CoCreateInstance, CoInitializeEx, CoInitializeSecurity, CoUninitialize},
oaidl,
objbase::COINIT_MULTITHREADED,
taskschd::{ITaskService, TaskScheduler},
},
Class, Interface,
}; // 0.3.7
fn main() {
// Create an instance of the Task Service.
let mut p_service: *mut ITaskService = unsafe { std::mem::zeroed() };
let hr = unsafe {
CoCreateInstance(
&TaskScheduler::uuidof(),
std::ptr::null_mut(),
CLSCTX_INPROC_SERVER,
&ITaskService::uuidof(),
&mut p_service as *mut *mut ITaskService as *mut *mut c_void,
)
};
// [...]
// // Connect to the task service.
// let hr = pService->Connect(_variant_t(), _variant_t(),
// _variant_t(), _variant_t());
let hr = unsafe {
(&mut *p_service).Connect(
oaidl::VARIANT { /* VT_EMPTY HERE */ },
oaidl::VARIANT { /* VT_EMPTY HERE */ },
oaidl::VARIANT { /* VT_EMPTY HERE */ },
oaidl::VARIANT { /* VT_EMPTY HERE */ },
)
};
}
文档说:
_variant_t( )
构造一个空的 _variant_t
对象,VT_EMPTY
.
我发现没有提及如何使用自述文件中所述的变体:
I found no mention on how to use the variant as stated in the README:
使用 std::mem::zeroed()
创建联合的实例,然后使用其中一种变体方法分配您想要的值.
Use
std::mem::zeroed()
to create an instance of the union, and then assign the value you want using one of the variant methods.
检查文档中的variant"时,列表中没有 _variant_t
fn,所以不确定它在 Rust 中的名称
When checking the docs for "variant", there's no _variant_t
fn on the list, so not sure what it is called in Rust
错误
field `0` of struct `winapi::um::oaidl::VARIANT_n1` is private
field `0` is private
为了
oaidl::VARIANT {
n1: oaidl::VARIANT_n1 {
0: [0, 0, 0]
}
}
推荐答案
初始化联合在 winapi
的自述文件:
Initializing unions is explained in winapi
's README:
使用 std::mem::zeroed()
创建联合的实例,然后使用其中一种变体方法分配您想要的值.
How do I create an instance of a union?
Use
std::mem::zeroed()
to create an instance of the union, and then assign the value you want using one of the variant methods.
例如,对于VARIANT_n1
,方法有n2
、n2_mut
、decVal
和decVal_mut
.您自然需要使用 _mut
方法来赋值.
For instance, for VARIANT_n1
, the methods are n2
, n2_mut
, decVal
and decVal_mut
. You will naturally need to use a _mut
method to assign a value.
请注意,从 winapi 0.3.7 开始,您还可以使用 Default::default()
来获取归零联合,而不是使用不安全的 std::mem::zeroed()
.您需要在 winapi
crate 上启用 impl-default
功能以实现 Default
trait.
Note that, starting with winapi 0.3.7, you can also use Default::default()
to obtain a zeroed union instead of using the unsafe std::mem::zeroed()
. You need to enable the impl-default
feature on the winapi
crate for the Default
trait to be implemented.
这篇关于如何在 Rust winapi 编程中使用 COM VARIANT?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!