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 */ },
)
};
}
The docs say:
_variant_t( )Constructs an empty_variant_tobject,VT_EMPTY.
I found no mention on how to use the variant as stated in the README:
Use
std::mem::zeroed()to create an instance of the union, and then assign the value you want using one of the variant methods.
When checking the docs for "variant", there's no _variant_t fn on the list, so not sure what it is called in Rust
Errors
field `0` of struct `winapi::um::oaidl::VARIANT_n1` is private
field `0` is private
for
oaidl::VARIANT {
n1: oaidl::VARIANT_n1 {
0: [0, 0, 0]
}
}
_variant_tis a c++ class so I suppose you must bind something to one of its constructor. Bindgen should be able to do it for you. How do you bind all this API so far ? Your question lack of detail._variant_tis just a C++ helper class that wraps a COMVARIANT, it automates memory management and reference counting forVARIANTvalues._variant_tdoesn't exist in other languages, like Rust, so you will have to construct aVARIANTmanually and populate it as needed.VARIANTis a tagged union, have a look at How Rust Implements Tagged Unions and A quick tour of Rust’s Type System Part 1: Sum Types (a.k.a. Tagged Unions)winuserenabled in Cargo features.VARIANT_n1is private and can't be used when usingVARIANT { n1: /*...*/ }.