gpt4 book ai didi

c++ - (Rust 题) C++ 双指针指向 void 的含义

转载 作者:行者123 更新时间:2023-12-03 10:04:25 30 4
gpt4 key购买 nike

我正在尝试通过遵循 Microsoft 为 ADSI API 和 Windows-RS crate 发布的 c++ 示例来使用 Rust 的事件目录。我不太明白这里发生了什么:
https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-adsopenobject
他们创建了一个指向 IAD 的未初始化指针(根据我的 c# 知识,它看起来像一个接口(interface))然后,当需要使用它时,他们有一个被强制转换为 void 的双指针。我试图在 Rust 中复制这种行为,但我想我只是不明白到底发生了什么。这是我迄今为止尝试过的:

// bindings omitted
use windows::Interface;
use libc::c_void;

fn main() -> windows::Result<()> {
let mut pads: *mut IADs = ptr::null_mut();
let ppads: *mut *mut c_void = pads as _;

unsafe {
let _ = CoInitialize(ptr::null_mut());
let mut ldap_root: Vec<u16> = "LDAP://rootDSE\0".encode_utf16().collect();
let hr = ADsOpenObject(
ldap_root.as_mut_ptr() as _,
ptr::null_mut(),
ptr::null_mut(),
ADS_AUTHENTICATION_ENUM::ADS_SECURE_AUTHENTICATION.0 as _,
& IADs::IID,
ppads,
);

if !hr.is_err() {
...
}

}

Ok(())
}
首先,创建空指针可能是错误的,因为这不是他们在示例中所做的,但问题是 rust 不允许使用未初始化的变量,所以我不确定是什么相当于是。
其次,大概 pADs 变量是输出应该去的地方,但我不理解有一个指针,然后是一个双指针,指向一个没有所有者的对象的交互。即使这在使用rust 中是可能的,但我觉得这不是我应该做的。
第三,一旦我通过 FFI 调用更新了指针,我如何告诉 Rust 生成的输出类型是什么,以便我们可以用它做更多的工作?做 as _ 行不通,因为它是一个结构,我觉得使用 transmute 不好

最佳答案

指针参数通常在 FFI 中用作与返回值本身一起返回数据的一种方式。这个想法是指针应该指向调用将填充结果的某个现有对象。由于 Windows API 函数经常返回 HRESULT s 表示成功和失败,它们使用指针返回其他内容。
在这种情况下,ADsOpenObject想要返回 *void (请求的 ADs 接口(interface)对象),因此您需要给它一个指向现有 *void 的指针它填充的对象:

let mut pads: *mut c_void = std::ptr::null_mut();
let ppads = &mut pads as *mut *mut c_void;

// or inferred inline

let hr = ADsOpenObject(
...
&mut pads as _,
);
我改了 pads*mut c_void简化此演示并匹配 ADsOpenObject参数。通话成功后可以投 pads任何你需要的。
关键区别在于类型转换 pads对比 &mut pads .你之前在做 ppadspads 相同的值从而告诉函数 *void结果应该写在 null .不好。这使得参数指向 pads反而。
而未初始化的 vs null差异是相当没有意义的,因为该函数的目标是无论如何都要覆盖它。

关于c++ - (Rust 题) C++ 双指针指向 void 的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66149124/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com