2
我正在尝试调用Rust的Win32 API CertOpenSystemsStoreW
和CertCloseStore
函数。当我这样做时,我在CertCloseStore
上遇到访问冲突,所以我想我在某些参数类型上的大小错误,但我看不到它。CertOpenSystemsStoreW或CertCloseStore的Rust FFI声明有什么问题?
下面的Python代码的工作(我有相当的工作C++,但不是很好的包含):
In [1]: import ctypes
In [2]: c32 = ctypes.windll.crypt32
In [3]: c32.CertOpenSystemStoreW.argtypes = [ctypes.c_void_p, ctypes.c_wchar_p]
In [4]: c32.CertOpenSystemStoreW.restype = ctypes.c_void_p
In [5]: c32.CertCloseStore.argtypes=[ctypes.c_void_p, ctypes.c_ulong]
In [6]: s = c32.CertOpenSystemStoreW(0, "my")
In [7]: c32.CertCloseStore(s, 0)
Out[7]: 1
这里是失败的防锈:
extern crate libc;
use libc::{c_ulong, c_int, c_void};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::ptr::null;
type HPROVIDER = c_void;
type HCERTSTORE = c_void;
type BOOL = c_int;
#[link(name = "Crypt32")]
extern "stdcall" {
fn CertOpenSystemStoreW(
hProv: *const HPROVIDER, szSubsystemProtocol: *const u16) -> HCERTSTORE;
fn CertCloseStore(
hCertStore: HCERTSTORE, dwFlags: c_ulong) -> BOOL;
}
fn to_utf16(s: &str) -> Vec<u16> {
let os_s = OsStr::new(s);
return os_s.encode_wide().chain(Some(0).into_iter()).collect::<Vec<_>>();
}
fn main() {
let protocol_utf16 = to_utf16("my");
let storehandle;
unsafe {
storehandle = CertOpenSystemStoreW(null(), protocol_utf16.as_ptr());
}
let freeresults;
unsafe {
freeresults = CertCloseStore(storehandle, 0);
}
println!("{}", freeresults);
}
我使用防锈1.16。
#1真的是真的吗?与其他操作系统中的常识和惯例相反,在Windows C编译器上,“unsigned long”实际上是32位的。 – user4815162342
@ user4815162342:是的,'DWORD'总是32位大小,请参见[Windows数据类型](https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx):“ * A ** 32位**无符号整数,范围为0到4294967295十进制*“64位版本为DWORDLONG,平台相关版本为DWORD_PTR。 –
@RemyLebeau是的,但'unsigned long'也是32位大小(在Windows上),所以'CertCloseStore'的签名实际上是正确的。 OP还报告使用'ctypes.c_ulong'工作的Python代码,这与此一致。 – user4815162342