小编Sci*_*eSE的帖子

如何通过原始指针传递闭包作为C函数的参数?

我正在使用Rust中的WinAPI,并且有一些函数(例如EnumWindows())需要回调.回调通常接受一个额外的参数(类型LPARAM是别名i64),您可以使用它将一些自定义数据传递给回调.

我已经将Vec<T>对象作为LPARAM 发送到WinAPI回调,它工作正常.例如,在我的情况下lparam,将一个值"解包" 到一个Vec<RECT>看起来像这样:

unsafe extern "system" fn enumerate_callback(hwnd: HWND, lparam: LPARAM) -> BOOL {
    let rects = lparam as *mut Vec<RECT>;
}
Run Code Online (Sandbox Code Playgroud)

我现在必须传递一个闭包,而不是传递一个向量.我不能使用函数指针,因为我的闭包必须捕获一些变量,如果我使用了函数则无法访问它们.在C++中,我会std::function<>用于我的特定任务,我认为在Rust中相应的抽象是一个闭包.

我的解包代码如下所示:

unsafe extern "system" fn enumerate_callback(hwnd: HWND, lparam: LPARAM) -> BOOL {
    let cb: &mut FnMut(HWND) -> bool = &mut *(lparam as *mut c_void as *mut FnMut(HWND) -> bool);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

SSCCE:

use std::os::raw::c_void;

fn enum_wnd_proc(some_value: i32, lparam: i32) {
    let …
Run Code Online (Sandbox Code Playgroud)

closures ffi traits rust

5
推荐指数
1
解决办法
1766
查看次数

显示来自 iOS 广播扩展的自定义错误消息

我的应用程序包由主应用程序(普通 iOS 应用程序)和广播扩展(ReplayKit 2)组成。我的应用程序包含一个按钮 ( RPSystemBroadcastPickerView),它会打开一个系统弹出窗口来选择一个广播扩展并启动它。

对扩展内部广播扩展的状态没有太多控制,但是继承的扩展类RPBroadcastSampleHandler有一个有用的方法 ( finishBroadcastWithError),它允许我们从扩展中触发失败(这将反过来结束扩展的进程并显示一个弹出窗口,显示一个错误和 2 个按钮)。

finishBroadcastWithError方法接受一个错误作为参数。但是,文档中绝对没有关于如何自定义此系统弹出窗口中显示的错误消息的信息。

我尝试谷歌以了解如何设置错误消息,因为我看到了一些应用程序(Mobcrush),当出现此弹出窗口时,它们以某种方式能够设置自定义错误消息。为了获得更多信息,我观看了 WWDC 2017 和 WWDC 2018 中关于 ReplayKit 2 的两个视频,唯一一张提到了 Replay Kit 2 中的错误处理的幻灯片,其中演示了以下代码:

let userInfo = [NSLocalizedFailureReasonErrorKey : "Not Logged In"]
let error = NSError(domain: "RPBroadcastErrorDomain", code: 401, userInfo: userInfo)
finishBroadcastWithError(error)
Run Code Online (Sandbox Code Playgroud)

我立即尝试了它,但不幸的是它对错误弹出窗口中显示的错误没有任何影响。我认为要么是 Replay Kit 2 中的一些错误,要么是某些内容已更改并且没有正确记录(由于某种原因,Replay Kit 2 没有很好的记录,我不得不从不同来源收集信息来编写一个应用程序)作品)。

我什至尝试在字典中设置多个不同的键,希望其中至少有一个会更改弹出窗口中的错误消息,但没有一个起作用。

func stop(message error: String) {
    let userInfo = [NSLocalizedDescriptionKey : error,
                    NSLocalizedRecoverySuggestionErrorKey : error,
                    NSLocalizedFailureErrorKey : error] …
Run Code Online (Sandbox Code Playgroud)

ios swift replaykit

3
推荐指数
1
解决办法
1004
查看次数

在 Rust 中使用 Objective-C 时管理 cocoa 内存的正确方法

我正在努力解决与可可基金会内存管理相关的一个问题。基本上我有一个用 Rust 编写的项目,我正在使用Objective-Ccocoa-rsobjc-rs与之交互。我熟悉CoreFoundation和CocoaFoundation中的内存管理(我已经阅读了文档中的相应文章)。当我使用 CoreFoundation 函数时,我没有遇到任何内存问题,但是当我使用 CocoaFoundation 相关的东西时,我遇到了很多问题,似乎从 CocoaFoundation 获取任何对象都会泄漏内存。

这是导致内存的函数之一的简化​​版本:

pub fn enumerate_apps()-> Vec<Rc<AppInfo>> {
    let mut apps_list = Vec::new();
    unsafe {
        let shared_workspace: *mut Object = msg_send![class("NSWorkspace"), sharedWorkspace];
        let running_apps: *mut Object = msg_send![shared_workspace, runningApplications];

        let apps_count = msg_send![running_apps, count];
        for i in 0..apps_count {
            let app: *mut Object = msg_send![running_apps, objectAtIndex:i];

            // Those ones are not used at the moment, but I actually need them,
            // I just removed all business logic to keep …
Run Code Online (Sandbox Code Playgroud)

cocoa objective-c ffi rust

1
推荐指数
1
解决办法
465
查看次数

标签 统计

ffi ×2

rust ×2

closures ×1

cocoa ×1

ios ×1

objective-c ×1

replaykit ×1

swift ×1

traits ×1