Как использовать COM VARIANT в программировании Rust winapi? - PullRequest
2 голосов
/ 13 июня 2019

Я пытаюсь преобразовать C ++ COM-код для TaskScheduler в Rust и застрял с аргументом VARIANT 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.

Я не нашел нетупоминание о том, как использовать вариант, как указано в README:

Используйте std::mem::zeroed() для создания экземпляра объединения, а затем присвойте нужное значение, используя один из методов варианта.

При проверке документов на "вариант" в списке нет _variant_t fn, поэтому не уверены, как он называется в 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]
    }
  }

1 Ответ

0 голосов
/ 14 июня 2019

Инициализация объединений объясняется в README winapi :

Как создать экземпляр объединения?

Использовать std::mem::zeroed()для создания экземпляра объединения, а затем присвойте нужное значение, используя один из вариантов вариантов.

Например, для VARIANT_n1, методы: n2, n2_mut, decVal и decVal_mut.Вам, естественно, потребуется использовать метод _mut для присвоения значения.

Обратите внимание, что вы также можете использовать Default::default() для получения обнуленного объединения вместо использования небезопасного std::mem::zeroed().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...