如何在winapi-rs中获取IWICImagingFactory实例
How to acquire instance of IWICImagingFactory in winapi-rs
所以在 my previous question I was advised to convert byte buffers to IStream
via SHCreateMemStream
and use IWICImagingFactory::CreateDecoderFromStream
. The first part already caused some complications as winapi-rs did contain an implementation 中 IStream
而不是函数本身 - 谢天谢地 winapi-rs
包含了我 link 所需的一切,如下所示:
pub type HIStream = *const IStream;
extern "system" {
pub fn SHCreateMemStream(pbInit: *const BYTE, cbInit: UINT) -> HIStream;
}
。
现在我遇到了与 IWICImagingFactory
class 类似的问题,我需要调用 CreateDecoderFromStream
方法。然而,根据 documentation 它需要一个 &self
参数并且类似于 IStream
是我理解的一个特征。如何在不从头开始实施的情况下获得 IWICImagingFactory
的新实例。我看到有人谈论一个叫做 CoCreateInstance
的函数和一些 com API 的细节,但那不是很清楚,因为我现在对 com API 的理解很差。
感谢评论中的建议,我通过查看 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);
P.S。 std::mem::uninitialized
已弃用且不安全且显然很糟糕,请记住这一点。
您的 与我的做法很接近。下面的代码有两个优点:
- 它生成一个正确类型的接口指针(
*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 的解决方案。
所以在 my previous question I was advised to convert byte buffers to IStream
via SHCreateMemStream
and use IWICImagingFactory::CreateDecoderFromStream
. The first part already caused some complications as winapi-rs did contain an implementation 中 IStream
而不是函数本身 - 谢天谢地 winapi-rs
包含了我 link 所需的一切,如下所示:
pub type HIStream = *const IStream;
extern "system" {
pub fn SHCreateMemStream(pbInit: *const BYTE, cbInit: UINT) -> HIStream;
}
。
现在我遇到了与 IWICImagingFactory
class 类似的问题,我需要调用 CreateDecoderFromStream
方法。然而,根据 documentation 它需要一个 &self
参数并且类似于 IStream
是我理解的一个特征。如何在不从头开始实施的情况下获得 IWICImagingFactory
的新实例。我看到有人谈论一个叫做 CoCreateInstance
的函数和一些 com API 的细节,但那不是很清楚,因为我现在对 com API 的理解很差。
感谢评论中的建议,我通过查看 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);
P.S。 std::mem::uninitialized
已弃用且不安全且显然很糟糕,请记住这一点。
您的
- 它生成一个正确类型的接口指针(
*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 的解决方案。