使用 N-API 在 Rust 中包装 Bcrypt 哈希函数时出现类型不匹配错误

问题描述 投票:0回答:1

我正在开发一个项目,需要在 Rust 中使用 N-API 包装 bcrypt 哈希函数。我编写了以下代码,但在编译过程中遇到类型不匹配错误。如果您能提供有关如何解决这些问题或改进我的方法的指导,我将不胜感激。

use bcrypt::hash;
use napi::{bindgen_prelude::*, Env, JsObject, JsString, Result, Task};
use napi_derive::napi;

struct BcryptTask {
    password: String,
    cost: u32,
}

impl Task for BcryptTask {
    type Output = String;
    type JsValue = JsString;

    fn compute(&mut self) -> Result<Self::Output> {
        hash(&self.password, self.cost)
            .map_err(|e| Error::new(Status::GenericFailure, format!("Bcrypt error: {:?}", e)))
    }

    fn resolve(&mut self, env: Env, output: Self::Output) -> Result<JsString> {
        env.create_string(&output)
    }
}

#[napi]
fn init(mut exports: JsObject) -> Result<()> {
    exports.create_named_method("hashPassword", hash_password_wrapper)?;
    Ok(())
}

#[napi]
fn hash_password_wrapper(env: Env, password: String, cost: u32) -> Result<JsObject> {
    let task = BcryptTask { password, cost };
    env.spawn(task)
}

我收到以下错误:

> cargo build
   Compiling rust_for_node v0.1.0 (C:\rust_for_node)
error[E0308]: mismatched types
   --> src\lib.rs:26:49
    |
26  |     exports.create_named_method("hashPassword", hash_password_wrapper)?;
    |             -------------------                 ^^^^^^^^^^^^^^^^^^^^^ expected "C" fn, found "Rust" fn
    |             |
    |             arguments to this method are incorrect
    |
    = note: expected fn pointer `unsafe extern "C" fn(*mut napi_env__, *mut napi_callback_info__) -> *mut napi_value__`
                  found fn item `fn(Env, std::string::String, u32) -> Result<JsObject, napi::Error> {hash_password_wrapper}`
note: method defined here
   --> C:\Users\xxx\.cargo\registry\src\index.crates.io-6f17d22bba15001f\napi-2.16.2\src\js_values\mod.rs:667:1
    |
667 | impl_object_methods!(JsObject);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `impl_object_methods` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> src\lib.rs:33:5
   |
31 | fn hash_password_wrapper(env: Env, password: String, cost: u32) -> Result<JsObject> {
   |                                                                    ---------------- expected `Result<JsObject, napi::Error>` because of return type
32 |     let task = BcryptTask { password, cost };
33 |     env.spawn(task)
   |     ^^^^^^^^^^^^^^^ expected `Result<JsObject, Error>`, found `Result<AsyncWorkPromise, ...>`
   |
   = note: expected enum `Result<JsObject, _>`
              found enum `Result<AsyncWorkPromise, _>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rust_for_node` (lib) due to 2 previous errors

问题:

如何解决使用exports.create_named_method时出现的类型不匹配错误?似乎需要一个“extern C”函数。 对于 env.spawn(task) 调用,它返回 AsyncWorkPromise 而不是 JsObject。我应该如何处理这个以满足函数的预期返回类型?

任何关于如何在 Rust 中正确实现这一点的帮助或建议将不胜感激!

node.js rust bcrypt node-native-addon
1个回答
0
投票

您需要使用 get_c_callback()

 生成的函数来调用 
napi
:

#[napi]
fn init(mut exports: JsObject) -> Result<()> {
    exports.create_named_method("hashPassword", get_c_callback(hash_password_wrapper)?)?;
    Ok(())
}

但是,请注意,

napi
会自动导出用
#[napi]
注释的函数,因此您不需要为此添加函数(您也可以使用
#[napi(js_name = "hashPassword")]
更改其名称)。

© www.soinside.com 2019 - 2024. All rights reserved.