Winapi 什么';CertOpenSystemsStoreW或CertCloseStore的此生锈FFI声明有何错误?
我试图从Rust调用Win32 APIWinapi 什么';CertOpenSystemsStoreW或CertCloseStore的此生锈FFI声明有何错误?,winapi,rust,ffi,Winapi,Rust,Ffi,我试图从Rust调用Win32 APICertOpenSystemsStoreW和CertCloseStore函数。当我这样做时,我在CertCloseStore上得到一个访问冲突,因此我想我在某些参数类型上的大小是错误的,但我看不到它 下面的Python代码工作(并且我有等效的工作C++,但没有被很好地包含): [1]中的:导入ctypes 在[2]中:c32=ctypes.windell.crypt32 在[3]中:c32.CertOpenSystemStoreW.argtypes=[cty
CertOpenSystemsStoreW
和CertCloseStore
函数。当我这样做时,我在CertCloseStore
上得到一个访问冲突,因此我想我在某些参数类型上的大小是错误的,但我看不到它
下面的Python代码工作(并且我有等效的工作C++,但没有被很好地包含):
[1]中的:导入ctypes
在[2]中:c32=ctypes.windell.crypt32
在[3]中:c32.CertOpenSystemStoreW.argtypes=[ctypes.c\u void\u p,ctypes.c\u wchar\u p]
在[4]中:c32.CertOpenSystemStoreW.restype=ctypes.c\u void\u p
[5]中:c32.CertCloseStore.argtypes=[ctypes.c\u void\u p,ctypes.c\u ulong]
在[6]中:s=c32.CertOpenSystemStoreW(0,“我的”)
[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);
}
extern板条箱libc;
使用libc::{c_ulong,c_int,c_void};
使用std::ffi::OsStr;
使用std::os::windows::ffi::OsStrExt;
使用std::ptr::null;
HPProvider类型=c_void;
HCERTSTORE类型=c_void;
类型BOOL=c_int;
#[链接(name=“Crypt32”)]
外部“stdcall”{
fn CertOpenSystemStoreW(
hProv:*常数HPProvider,SZSSubsystemprotocol:*常数u16)->HCERTSTORE;
fn CertCloseStore(
hCertStore:hCertStore,dwFlags:c_ulong)->BOOL;
}
fn至utf16(s:&str)->Vec{
让os_s=OsStr::new(s);
返回os_.encode_wide().chain(一些(0).到_iter())。collect::();
}
fn main(){
让协议_utf16=to_utf16(“my”);
让店主来处理;
不安全{
storehandle=CertOpenSystemStoreW(null(),协议_utf16.as_ptr());
}
让自由的结果;
不安全{
freeresults=CertCloseStore(storehandle,0);
}
println!(“{}”,freesults);
}
我使用的是Rust 1.16。嗯,有两个问题:
c_void
不是指针类型-它只是u8
。因此,我上面的代码应该类似于typehprovider=*constc\uvoid代码>(这不太好,因为它使所有HPProviders都是常量,但我看不到一种方法可以在不指定“mut”或“const”的情况下执行锈式指针typedef)
1真的是真的吗?与其他操作系统中的常识和实践不同,
无符号长
在Windows C编译器上实际上是32位的。@user4815162342:是的,DWORD
的大小总是32位的,请参阅:“32位无符号整数。范围是0到4294967295十进制。”64位版本是DWORDLONG
,与平台相关的版本是DWORD\u PTR
@RemyLebeau是的,但是无符号长的
也总是32位大小(在Windows上),因此CertCloseStore
的签名实际上是正确的。OP还报告了使用ctypes.c_ulong
工作的Python代码,这与此一致。@user4815162342:我没有对此进行辩论。我只是在评论你的“1真的是真的吗?”问题。@RemyLebeau不幸的是,文档中的定义是以Linux为中心的,因为文档仅在Linux上生成。(这是Rust文档中的一个已知问题,它也没有记录特定于Windows的对stdlib的扩展,例如问题中使用的std::os::Windows::ffi::OsStrExt
)我同意定义不那么模糊更好-我建议从winapi板条箱导入例如winapi::minwindef::DWORD
。话虽如此,我仍在质疑答案中#1分的正确性;从这个问题上看,这次崩溃很可能是由#2引起的。