win_wrap/
com.rs

1/*
2 * Copyright (c) 2023. The RigelA open source project team and
3 * its contributors reserve all rights.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and limitations under the License.
12 */
13
14pub mod persist;
15
16use crate::{common::HRESULT, ext::VecExt};
17use std::ffi::c_void;
18use windows::Win32::System::{
19    Com::{CoInitializeEx, CoUninitialize, COINIT_MULTITHREADED, SAFEARRAY},
20    Ole::{SafeArrayDestroy, SafeArrayGetElement, SafeArrayGetLBound, SafeArrayGetUBound},
21};
22
23/**
24使用多线程模型套间(Multi Thread Apartment, MTA)初始化COM调用。
25MTA能充分利用多核CPU,提高程序性能,但要注意线程之间同步的安全问题。
26*/
27pub fn co_initialize_multi_thread() -> HRESULT {
28    unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }
29}
30
31//noinspection SpellCheckingInspection
32/**
33关闭当前线程的COM库,卸载线程加载的所有dll,释放任何其他的资源,关闭在线程上维护所有的RPC连接。
34*/
35pub fn co_uninitialize() {
36    unsafe { CoUninitialize() }
37}
38
39impl<T> VecExt<T> for *const SAFEARRAY {
40    fn to_vec(self) -> Vec<T> {
41        unsafe {
42            let mut v = vec![];
43            let a = SafeArrayGetLBound(self, 1).unwrap();
44            let b = SafeArrayGetUBound(self, 1).unwrap();
45            for i in a..=b {
46                let mut e: T = std::mem::zeroed();
47                SafeArrayGetElement(self, &i, &mut e as *mut T as *mut c_void).unwrap_or(());
48                v.push(e);
49            }
50            SafeArrayDestroy(self).unwrap_or(());
51            v
52        }
53    }
54}