Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 什么';CertOpenSystemsStoreW或CertCloseStore的此生锈FFI声明有何错误?_Winapi_Rust_Ffi - Fatal编程技术网

Winapi 什么';CertOpenSystemsStoreW或CertCloseStore的此生锈FFI声明有何错误?

Winapi 什么';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

我试图从Rust调用Win32 API
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。

嗯,有两个问题:

  • DWORD是32位的,不管您是在64位还是32位的windows上(我想这是有道理的)。所以我的CertCloseStore的第二个论点是错误的
  • 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引起的。