You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Rust+N-API封装Bcrypt哈希函数时的类型不匹配错误

Rust N-API封装bcrypt哈希函数的编译错误修复

错误1:create_named_method类型不匹配

问题原因

create_named_method要求传入C语言调用约定的函数指针,但被#[napi]宏修饰的hash_password_wrapper是Rust函数——宏会自动生成C兼容的包装层,不能直接作为参数传入该方法。

修复方案

无需手动调用create_named_method添加方法,#[napi]宏会自动处理函数的导出逻辑。直接移除init函数中手动添加方法的代码,完全依赖宏的自动导出能力即可。


错误2:env.spawn返回值类型不匹配

问题原因

env.spawn(task)返回的是AsyncWorkPromise类型(对应Node.js的Promise对象),但函数声明的返回类型是Result<JsObject>,二者类型不兼容。

修复方案

将函数返回类型改为Result<AsyncWorkPromise>,napi库会自动将AsyncWorkPromise转换为Node.js可识别的Promise对象;也可以通过.into()方法将AsyncWorkPromise转换为JsObject(因为AsyncWorkPromise实现了Into<JsObject> trait),前者更符合异步函数的常规写法。


完整修正代码

use bcrypt::hash;
use napi::{bindgen_prelude::*, Env, JsString, Result, Task, AsyncWorkPromise};
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]宏自动导出函数到Node.js环境
#[napi]
fn hash_password(env: Env, password: String, cost: u32) -> Result<AsyncWorkPromise> {
    let task = BcryptTask { password, cost };
    env.spawn(task)
}

// 若需自定义导出逻辑,可保留init但无需手动添加方法,#[napi]会自动处理
// #[napi]
// fn init(mut exports: JsObject) -> Result<()> {
//     Ok(())
// }

代码说明

  1. 移除手动调用create_named_method的代码,完全依赖#[napi]宏完成函数导出。
  2. 调整函数返回类型为Result<AsyncWorkPromise>,与env.spawn的返回值类型匹配,napi会自动将其转换为Node.js的Promise。
  3. 函数名改为更简洁的hash_password,符合常规命名习惯。

内容的提问来源于stack exchange,提问作者Nico AD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:43:11