#com-interface #com #winapi #windows

com-impl

从Rust自动实现Win32 COM接口,并提供一些有用的辅助类型以完成此任务

5个版本

0.2.0 2023年7月25日
0.1.1 2019年3月1日
0.1.0 2019年3月1日
0.1.0-alpha22018年11月11日

#91Windows APIs

Download history 22/week @ 2024-04-06 28/week @ 2024-04-13 35/week @ 2024-04-20 29/week @ 2024-04-27 27/week @ 2024-05-04 33/week @ 2024-05-11 24/week @ 2024-05-18 26/week @ 2024-05-25 33/week @ 2024-06-01 18/week @ 2024-06-08 24/week @ 2024-06-15 29/week @ 2024-06-22 7/week @ 2024-06-29 7/week @ 2024-07-06 29/week @ 2024-07-13 17/week @ 2024-07-20

64 每月下载量
用于 3 个crate (2 直接)

MIT 协议

10KB
64

com-impl

从Rust自动实现Win32 COM接口,并提供一些有用的辅助类型以完成此任务。

提供IUnknown的自动实现,并在您使用#[derive(ComImpl)]您的类型时自动使用原子引用计数类型。

#[repr(C)]
#[derive(com_impl::ComImpl)]
#[interfaces(IDWriteFontFileStream)] // IUnknown is implicit in this list
pub struct FileStream {
    vtbl: com_impl::VTable<IDWriteFontFileStreamVtbl>,
    refcount: com_impl::Refcount,
    write_time: u64,
    file_data: Vec<u8>,
}

impl FileStream {
    pub fn new(write_time: u64, data: Vec<u8>) -> ComPtr<IDWriteFontFileStream> {
        let ptr = FileStream::create_raw(write_time, data);
        let ptr = ptr as *mut IDWriteFontFileStream;
        unsafe { ComPtr::from_raw(ptr) }
    }
}

#[com_impl::com_impl]
unsafe impl IDWriteFontFileStream for FileStream {
    unsafe fn get_file_size(&self, size: *mut u64) -> HRESULT {
        *size = self.file_data.len() as u64;
        S_OK
    }

    unsafe fn get_last_write_time(&self, write_time: *mut u64) -> HRESULT {
        *write_time = self.write_time;
        S_OK
    }

    unsafe fn read_file_fragment(
        &self,
        start: *mut *const c_void,
        offset: u64,
        size: u64,
        ctx: *mut *mut c_void,
    ) -> HRESULT {
        if offset > std::isize::MAX as u64 || size > std::isize::MAX as u64 {
            return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
        }

        let offset = offset as usize;
        let size = size as usize;

        if offset + size > self.file_data.len() {
            return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
        }

        *start = self.file_data.as_ptr().offset(offset as isize) as *const c_void;
        *ctx = std::ptr::null_mut();

        S_OK
    }

    unsafe fn release_file_fragment(&self, _ctx: *mut c_void) {
        // Nothing to do
    }
}

fn main() {
    let ptr = FileStream::new(100, vec![0xDE, 0xAF, 0x00, 0xF0, 0x01]);

    // Do things with ptr
}

依赖关系

~0–465KB