如何在winapi-rs中获取IWICImagingFactory的实例
Posted
技术标签:
【中文标题】如何在winapi-rs中获取IWICImagingFactory的实例【英文标题】:How to acquire instance of IWICImagingFactory in winapi-rs 【发布时间】:2021-10-22 14:49:48 【问题描述】:所以在my previous question 中,我被建议通过SHCreateMemStream
将字节缓冲区转换为IStream
并使用IWICImagingFactory::CreateDecoderFromStream
。第一部分已经引起了一些复杂性,因为 winapi-rs 确实包含 implementation 用于 IStream
但不是函数本身 - 谢天谢地 winapi-rs
包含我需要链接它的所有内容,如下所示:
pub type HIStream = *const IStream;
extern "system"
pub fn SHCreateMemStream(pbInit: *const BYTE, cbInit: UINT) -> HIStream;
。
现在我面临与IWICImagingFactory
类类似的问题,我需要调用CreateDecoderFromStream
方法。但是,根据documentation,它需要一个&self
参数,并且与IStream
类似,这是我理解的一个特征。如何在不从头开始实施的情况下获得IWICImagingFactory
的新实例。我看到一些关于名为 CoCreateInstance
的函数和一些 com API 细节的讨论,但这不是很清楚,因为我目前对 com API 的理解非常差。
【问题讨论】:
WIC API Overview 的示例代码解释了如何创建IWICImagingFactory
实例。您需要做的就是将其音译成 Rust 代码。
也就是说,windows 在处理 COM 方面已经明显优于 winapi,后者在一年多前收到了最后一次更新。 winapi-rs 没有太多未来。
【参考方案1】:
您的proposed answer 与我所做的很接近。下面的代码有两个优点:
它产生一个正确类型的接口指针 (*mut IWICImagingFactory
)
不依赖uninitialized()
let mut factory: *mut IWICImagingFactory = std::ptr::null_mut();
let hr = unsafe
CoCreateInstance(
&CLSID_WICImagingFactory,
std::ptr::null_mut(),
CLSCTX_INPROC_SERVER,
&IWICImagingFactory::uuidof(),
&mut factory as *mut *mut _ as *mut *mut _,
)
;
这样你就有了一个指向IWICImagingFactory
的指针,你可以立即使用,例如
let mut decoder: *mut IWICBitmapDecoder = std::ptr::null_mut();
let hr = unsafe
(*factory).CreateDecoderFromStream(
&mut stream, // An IStream providing the image data
std::ptr::null_mut(),
options, // Needs to be constructed elsewhere
&mut decoder as *mut *mut _ as *mut *mut _,
)
;
错误处理和资源管理大多是手动的,并且已从代码中省略(您可以使用FAILED
函数来确定成功或失败。错误退出仍然需要您通过对Release
的相应调用进行清理。
windows crate 为 COM 接口提供资源管理包装器,使清理成为堆栈展开的一部分。最终效果是错误传播远没有那么冗长和手动。如果你有兴趣,我也可以提供基于windows
crate 的解决方案。
【讨论】:
【参考方案2】:感谢评论中的建议,我通过查看WIC API Overview 找到了一种方法 - 但是由于我想添加允许我做这件事的代码的方式存在一些问题。 (绝不是一个好的防锈代码 - 但它肯定可以工作)。
let mut pFactory: *mut c_void = uninitialized();
let hr = CoCreateInstance(&CLSID_WICImagingFactory as *const IID,
null_mut(),
CLSCTX_INPROC,
&IWICImagingFactory::uuidof(),
&mut pFactory as *mut *mut c_void);
附: std::mem::uninitialized
已弃用且不安全且显然很糟糕,请记住这一点。
【讨论】:
以上是关于如何在winapi-rs中获取IWICImagingFactory的实例的主要内容,如果未能解决你的问题,请参考以下文章