简体   繁体   English

如何使闭包键入“ extern“ C” fn”

[英]How to make a closure typed 'extern “C” fn'

This is short example about this question. 这是关于这个问题的简短示例。

#[fixed_stack_segment]
fn test(func: extern "C" fn() -> ~str) -> ~str {
    func()
}
extern "C" fn func1() -> ~str {
    ~"hello"
}

fn main() {
    let func2 = || -> ~str { ~"world" };
    println(test(func1));
    println(test(func2));
}

Then, rustc stops with error. 然后,rustc因错误而停止。

st.rs:13:17: 13:22 error: mismatched types: expected `extern "C" fn() -> ~str` but found `&fn<no-bounds>() -> ~str` (expected extern fn but found fn)
st.rs:13     println(test(func2));

I cannot find a way to make the lambda be an extern fn. 我找不到使lambda成为外部fn的方法。

What should I do? 我该怎么办?

The closure syntax is always either &fn or ~fn , and to make an extern "ABI" fn (for any value of ABI , including Rust ), one needs to use a full function declaration. 关闭语法始终为&fn~fn ,并且要使extern "ABI" fn (对于ABI任何值,包括Rust ),都需要使用完整的函数声明。

#[fixed_stack_segment]
fn test(func: extern "C" fn() -> ~str) -> ~str {
    func()
}
extern "C" fn func1() -> ~str {
    ~"hello"
}

fn main() {
    extern "C" fn func2() -> ~str { ~"world" } 

    println(test(func1));
    println(test(func2));
}

There is some talk of allowing lambdas to create non-closures too, with the ABI inferred like anything else in a type signature, but this isn't implemented yet. 有人说过也允许lambda创建非闭包,就像在类型签名中以其他方式推断出ABI一样,但这尚未实现。


However, as Vladimir Matveev says, there is a fundamental difference between closures and normal functions, which means that one will never be able to use all the features of closures when passed as an extern fn . 但是,正如弗拉基米尔·马特维耶夫(Vladimir Matveev)所说,闭包和普通函数之间存在根本的区别,这意味着当作为extern fn函数extern fn传递时,将永远无法使用闭包的所有功能。 The difference is closures can capture (references to) variables, ie 区别在于闭包可以捕获(引用)变量,即

let n = 1;
let f = || { n + 1 }; 

This means a closure is effectively represented by 这意味着闭包有效地表示为

struct AndFn { // &fn
    env: &Environment,
    func: extern "Rust" fn()
}

struct TwiddleFn { // ~fn
    env: ~Environment,
    func: extern "Rust" fn()
}

where Environment is a struct that contains all the capture variables for that closure (it differs for each &fn , since each one captures different things); 其中Environment是一个结构,其中包含该闭包的所有捕获变量(每个&fn有所不同,因为每个捕获不同的事物); the func is a function pointer to the code of the closure, which is what gets executed when the closure is called; func是指向闭包代码的函数指针,闭包代码是在调用闭包时执行的; if a closure captures any variables, the func will require the env to exist. 如果闭包捕获任何变量,则func将要求env存在。 Thus, the lambda syntax will only be able to create plain extern fn s when it captures no variables. 因此,lambda语法仅在不捕获任何变量时才能够创建普通extern fn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM