ohos_rust_binding 0.1.0

Rust binding for OHOS
Documentation
use crate::napi::napi_status::napi_ok;
use crate::{log, napi::*};
use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::c_void;
use std::ptr::null_mut;

/// Encapsulate the ArkTS callback and save the callback to func: *mut napi_threadsafe_function.
///
/// TODO: thread_safe_func_call_ark_ts should be passed in as a parameter
#[allow(improper_ctypes_definitions)]
pub extern "C" fn native_call_ark_ts_common(
    env: napi_env,
    info: napi_callback_info,
    func_name: String,
    func: *mut napi_threadsafe_function,
) -> napi_value {
    let mut args: [napi_value; 1] = [null_mut(); 1];
    let mut argc = args.len();

    unsafe {
        let str_len = func_name.len();
        let mut func_name_nvalue = null_mut();
        let c_str = CString::new(func_name).unwrap_or_default();
        let c_str_ptr: *const ::std::os::raw::c_char = c_str.as_ptr();
        napi_create_string_utf8(env, c_str_ptr, str_len + 1, &mut func_name_nvalue);

        napi_get_cb_info(
            env,
            info,
            &mut argc,
            args.as_mut_ptr(),
            null_mut(),
            null_mut(),
        );

        let _ = napi_create_threadsafe_function(
            env,
            args[0],
            null_mut(),
            func_name_nvalue,
            0,
            1,
            null_mut(),
            None,
            null_mut(),
            Some(thread_safe_func_call_ark_ts),
            func,
        );

        return null_mut();
    }
}

pub unsafe fn c_void_to_string(ptr: *mut c_void) -> String {
    let cstr_ptr: *const std::os::raw::c_char = unsafe { mem::transmute(ptr) };
    let c_str = CStr::from_ptr(cstr_ptr);
    c_str.to_string_lossy().into_owned()
}

pub unsafe fn string_to_c_void(content: String) -> *mut c_void {
    let c_string = CString::new(content).unwrap_or_default();
    let c_void_ptr: *mut c_void = c_string.into_raw() as *mut c_void;
    c_void_ptr
}

/// Execution logic of the arkts callback.
///
/// This function is encapsulated into a secure function in native_call_ark_ts_common.
///
/// This function is applicable to the scenario where the callback parameter is string.
pub extern "C" fn thread_safe_func_call_ark_ts(
    env: napi_env,
    js_callback: napi_value,
    _context: *mut c_void,
    data: *mut c_void,
) {
    unsafe {
        let value = c_void_to_string(data);
        let value_len = value.as_bytes().len();
        let c_str = CString::new(value).unwrap_or_default();
        let c_str_ptr: *const ::std::os::raw::c_char = c_str.as_ptr();
        let mut data: napi_value = null_mut();
        if napi_create_string_utf8(env, c_str_ptr, value_len + 1, &mut data) == napi_ok {
            log::info("rust_call_arkts", "create callback source success\n");
        }

        let status = napi_call_function(env, null_mut(), js_callback, 1, &mut data, null_mut());
        if status != napi_ok {
            log::error("rust_call_arkts", "call js call back function failed\n");
        }
    }
}