我正在尝试从Rust调用Win32 API CertOpenSystemsStoreW
和CertCloseStore
函数。当我这样做时,我在CertCloseStore
上遇到了访问冲突,所以我想我的某些参数类型的大小有误,但我看不到它。
以下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
这是失败的Rust:
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);
}
我正在使用Rust 1.16。
答案 0 :(得分:1)
嗯,有两个问题:
c_void
不是指针类型 - 它只是u8
。所以我上面的代码应该类似于type HPROVIDER = *const c_void;
(这不是很好,因为它使所有HPROVIDER成为常量,但我没有看到一种方法来执行Rust样式指针typedef而不指定'mut'或'const的')。