feat(android-ffi): nativeLastErrorKind 出口带错误分类(3a)
LAST_ERROR 槽位改存 (kind, detail),新增 nativeLastErrorKind();FFI 契约 kind 先取、message 后取(消息读走清空槽位)。kind 编号与 viewer_core:: ConnectErrorKind::code 一致,跨 FFI 只传整数。JNI 符号 12→13 全部导出(字节扫描核)。
This commit is contained in:
parent
4eb82f9779
commit
f28db050fb
@ -34,7 +34,8 @@ struct SessionBox {
|
||||
runtime: tokio::runtime::Runtime,
|
||||
}
|
||||
|
||||
/// 连接被控端。成功返回句柄(>0),失败返回 0;错误消息经 `nativeLastError()` 取。
|
||||
/// 连接被控端。成功返回句柄(>0),失败返回 0;错误消息经 `nativeLastError()` 取,
|
||||
/// **错误分类**经 `nativeLastErrorKind()` 取(3a:界面按分类显示中文文案,原始英文作第二行)。
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_verify_remote_RustBridge_nativeConnect<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
@ -46,14 +47,14 @@ pub extern "system" fn Java_com_verify_remote_RustBridge_nativeConnect<'local>(
|
||||
let host_s = match env.get_string(&host) {
|
||||
Ok(s) => s.to_string_lossy().into_owned(),
|
||||
Err(_) => {
|
||||
set_last_error("host 参数不是合法字符串");
|
||||
set_last_error(-1, "host 参数不是合法字符串");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
let code_s = match env.get_string(&code) {
|
||||
Ok(s) => s.to_string_lossy().into_owned(),
|
||||
Err(_) => {
|
||||
set_last_error("code 参数不是合法字符串");
|
||||
set_last_error(-1, "code 参数不是合法字符串");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -64,7 +65,7 @@ pub extern "system" fn Java_com_verify_remote_RustBridge_nativeConnect<'local>(
|
||||
.build()
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(format!("runtime init: {e}")),
|
||||
Err(e) => return Err((-1i32, format!("runtime init: {e}"))),
|
||||
};
|
||||
let cfg = ConnectConfig::direct(host_s, port as u16, code_s);
|
||||
match runtime.block_on(Session::connect(cfg)) {
|
||||
@ -72,53 +73,73 @@ pub extern "system" fn Java_com_verify_remote_RustBridge_nativeConnect<'local>(
|
||||
session: Arc::new(session),
|
||||
runtime,
|
||||
}),
|
||||
Err(e) => Err(format!("{e:#}")),
|
||||
// ConnectError 的 Display 即原始 detail;kind.code() 与
|
||||
// viewer_core::ConnectErrorKind::code 的映射表一致(FFI 契约)。
|
||||
Err(e) => Err((e.kind.code(), e.detail)),
|
||||
}
|
||||
});
|
||||
|
||||
match built {
|
||||
Ok(Ok(boxed)) => {
|
||||
set_last_error("");
|
||||
set_last_error(0, "");
|
||||
Box::into_raw(Box::new(Mutex::new(boxed))) as jlong
|
||||
}
|
||||
Ok(Err(msg)) => {
|
||||
set_last_error(&msg);
|
||||
Ok(Err((kind, msg))) => {
|
||||
set_last_error(kind, &msg);
|
||||
0
|
||||
}
|
||||
Err(_) => {
|
||||
set_last_error("panic in nativeConnect");
|
||||
set_last_error(-1, "panic in nativeConnect");
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_last_error(msg: &str) {
|
||||
/// kind = 0 表示清除;-1 表示 FFI 层自身错误(无 viewer-core 分类,Kotlin 走 Other 文案)。
|
||||
fn set_last_error(kind: i32, msg: &str) {
|
||||
let mut slot = LAST_ERROR.lock().unwrap();
|
||||
if msg.is_empty() {
|
||||
*slot = None;
|
||||
} else {
|
||||
*slot = Some(msg.to_string());
|
||||
*slot = Some((kind, msg.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
static LAST_ERROR: Mutex<Option<String>> = Mutex::new(None);
|
||||
static LAST_ERROR: Mutex<Option<(i32, String)>> = Mutex::new(None);
|
||||
|
||||
/// 取最近一次 nativeConnect 的错误消息(无错误返回 null)。
|
||||
/// FFI 契约:调用方必须先 `nativeLastErrorKind()` 再 `nativeLastError()`——
|
||||
/// 本函数读走消息时**清空整个槽位**(kind 一起失效),颠倒顺序会拿到 kind=0。
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_verify_remote_RustBridge_nativeLastError<'local>(
|
||||
env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
) -> jstring {
|
||||
let msg = LAST_ERROR.lock().unwrap().take();
|
||||
let mut slot = LAST_ERROR.lock().unwrap();
|
||||
let msg = slot.as_ref().map(|(_, m)| m.clone());
|
||||
match msg {
|
||||
Some(m) => env
|
||||
.new_string(m)
|
||||
.map(|s| s.into_raw())
|
||||
.unwrap_or(std::ptr::null_mut()),
|
||||
Some(m) => {
|
||||
*slot = None;
|
||||
env.new_string(m)
|
||||
.map(|s| s.into_raw())
|
||||
.unwrap_or(std::ptr::null_mut())
|
||||
}
|
||||
None => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 取最近一次 nativeConnect 的错误分类码(viewer_core::ConnectErrorKind::code)。
|
||||
/// 只读不清空;0 = 无错误,-1 = FFI 层自身错误(参数非法/panic/runtime 初始化失败,
|
||||
/// 无 viewer-core 分类,Kotlin 按 Other 文案 + 原始消息显示)。
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_verify_remote_RustBridge_nativeLastErrorKind(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
) -> jint {
|
||||
let slot = LAST_ERROR.lock().unwrap();
|
||||
slot.as_ref().map(|(k, _)| *k).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// 取下一帧(阻塞直到有帧或会话结束)。返回 null = 会话结束。
|
||||
/// 仅允许解码线程调用;destroy 前必须先停止本线程(见文件头锁纪律)。
|
||||
#[no_mangle]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user