OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI 常见的函数详解(二)

引言

前面一篇文章OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI(一)介绍了NAPI的基础理论知识,今天重点介绍下NAPI中重要的函数。

一、Native 侧的NAPI的相关的C++函数

以下面一段代码为例介绍下主要函数的功能和用法。

napi_value MSLiteModelNapi::Init(napi_env env, napi_value exports) {napi_property_descriptor properties[] = {DECLARE_NAPI_FUNCTION("getInputs", GetInputs),DECLARE_NAPI_FUNCTION("predict", PredictAsync)};napi_property_descriptor staticProperty[] = {DECLARE_NAPI_STATIC_FUNCTION("loadModelFromFile", LoadMSLiteModelFromFile),DECLARE_NAPI_PROPERTY("Format", CreateFormatObject(env)),DECLARE_NAPI_PROPERTY("DataType", CreateDataTypeObject(env)),DECLARE_NAPI_PROPERTY("ThreadAffinityMode", CreateThreadAffinityModeObject(env)),};napi_value constructor = nullptr;napi_status status = napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &constructor);status = napi_create_reference(env, constructor, REFERENCE_CREATION_COUNT, &constructor_);status = napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor);status = napi_define_properties(env, exports, sizeof(staticProperty) / sizeof(staticProperty[0]), staticProperty);return exports;
}

1、DECLARE_NAPI_FUNCTION

宏接收两个参数:

  • name:是要定义的函数的名字。
  • func:是对应的函数实现。
    宏展开后,它创建了一个结构体(可能是napi_property_descriptor),该结构体包含了以下字段:
  • name:函数的名字。
  • method:函数的实现。
    其他一些字段被设置为nullptr或者默认值,这些可能涉及到函数的属性、 getter、setter、enumerator、data以及属性标志等。这个宏的主要作用是简化N-API函数的定义过程,使得开发者不需要手动填写所有的结构体字段,只需提供函数名和实现即可。
#define DECLARE_NAPI_FUNCTION(name, func)                                         \{                                                                             \(name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr \}

func是一个 C++ 函数,它被声明为 NAPI 函数 “func”。然后,这个函数被添加到导出的对象中,这样 JavaScript 代码就可以通过 require 函数引入并调用它。

2、DECLARE_NAPI_STATIC_FUNCTION

DECLARE_NAPI_STATIC_FUNCTION 宏用于声明一个静态函数,可以直接通过模块名直接调用。该函数将被导出为 NAPI 函数,这样 JavaScript 代码就可以通过 require 函数引入并调用它。其他与DECLARE_NAPI_FUNCTION大同小异。

#define DECLARE_NAPI_STATIC_FUNCTION(name, func)                                 \{                                                                            \(name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr \}

选择使用 DECLARE_NAPI_STATIC_FUNCTION 还是 DECLARE_NAPI_FUNCTION 取决于你的函数是否需要与类的实例关联。如果你正在编写一个不需要类上下文的独立函数,应该使用静态函数。如果你正在实现一个类,并且函数是类的一部分,那么应该使用非静态函数。

napi_value MethodA(napi_env env, napi_callback_info info) {// 实现具体的函数逻辑// ...return nullptr;
}NAPI_EXPORT NAPI_INIT() {...// 声明 NAPI 函数DECLARE_NAPI_STATIC_FUNCTION("methodA", MethodA);...
}

3、DECLARE_NAPI_PROPERTY

宏在 NAPI(Node.js API)中用于声明一个属性,这个属性可以是静态的或者属于某个对象的实例。属性在 NAPI 中可以被视为只读或可写的数据成员,它们允许你将 C/C++ 中的变量或常量暴露给 JavaScript 代码。

#define DECLARE_NAPI_PROPERTY(name, val)\                                     
{                                                        \                                                        
(name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr \
}

使用 DECLARE_NAPI_PROPERTY 宏时,你需要提供以下信息:

  • 属性名称:这是在 JavaScript 代码中访问该属性时使用的名称。
  • 获取函数:一个可选的函数,当 JavaScript 代码尝试读取属性时被调用。
  • 设置函数:一个可选的函数,当 JavaScript 代码尝试设置属性的值时被调用。
  • 属性值:对于常量属性,这是属性的初始值
#include <napi.h>Napi::Value GetMyProperty(const Napi::CallbackInfo& info) {// 返回属性值return Napi::Value::From(info.Env(), 42);
}void SetMyProperty(const Napi::CallbackInfo& info, const Napi::Value& value) {// 处理属性值的设置// 这里可以添加代码来处理 value 参数
}Napi::Object Init(Napi::Env env, Napi::Object exports) {// 使用 DECLARE_NAPI_PROPERTY 宏声明属性DECLARE_NAPI_PROPERTY("MyProperty", GetMyProperty, SetMyProperty);// 将声明的属性添加到模块的导出对象中exports.Set("MyProperty", MyProperty);return exports;
}NODE_API_MODULE(myaddon, Init)

4、DECLARE_NAPI_STATIC_PROPERTY

DECLARE_NAPI_PROPERTY 和 DECLARE_NAPI_STATIC_PROPERTY 是两个用于声明属性的宏,它们之间的主要区别在于属性的生命周期和作用域,DECLARE_NAPI_PROPERTY 用于声明一个与对象实例关联的属性,通常是可读写的,并且通过对象的实例来访问和修改;DECLARE_NAPI_STATIC_PROPERTY 用于声明一个静态属性,它属于类或模块,而不是某个特定的实例。静态属性通常是只读的,或者具有相同的getter和setter函数,这些函数不会依赖于对象的状态。

5、napi_define_class

Node.js API (NAPI) 中的一个函数,用于在 Node.js 环境中定义一个新的 JavaScript 函数,该函数可以创建一个对象的实例。这个函数通常用于将 C/C++ 中的类封装为 Node.js 模块中的构造函数,使得 JavaScript 代码可以通过这个构造函数创建对象实例,并调用其方法和访问其属性。

napi_status napi_define_class(napi_env env,const char* class_name,size_t constructor_name_count,const napi_property_descriptor* property_descriptors,napi_value constructor_function,napi_value* constructor_name);

其中参数说明:

env:指向当前环境的指针。
class_name:新类名的字符串。
constructor_name_count:构造函数名称的数量,通常为 1。
property_descriptors:指向一个 napi_property_descriptor 数组的指针,该数组描述了类的属性和方法。
constructor_function:一个 napi_value,表示构造函数,当调用构造函数时,会调用指定的 JavaScript 函数。
constructor_name:一个 napi_value 数组,包含与 constructor_function 对应的名称。
napi_property_descriptor 结构体用于描述类的属性和方法,其原型如下:

typedef struct {const char* name;             // 属性或方法的名称napi_value getter;             // 获取器函数,如果属性是只读的,则设置为 NULLnapi_value setter;             // 设置器函数,如果属性是只写的,则设置为 NULLnapi_value method;            // 方法函数,如果属性不是方法,则设置为 NULLnapi_value enum_value;        // 枚举值,通常设置为 NULLnapi_value default_value;      // 默认值,通常设置为 NULL
} napi_property_descriptor;

OpenHarmony NAPI 提供了一种“包装”C ++类和实例的方法,以便 JS 应用可以调用类的构造函数和方法。

Node.js Node-API 中关于导出类对象的内容,参考链接 : https:// nodejs.org/docs/latest-v14.x/api/n-api.html#n_api_object_wrap

NAPI 导出类对象流程

  • 通过napi_define_class定义一个 JS 类
  • 它包含了与 C++ 类对应的构造函数、静态属性、方法、实例属性和方法。
  • 通过napi_wrap将 C++ 实例绑定在 JS 对象中
  • 当 JS 代码调用构造函数时,构造函数回调会使用 napi_wrap 将一个新的 C++ 实例绑定在 JS 对象中,然后返回绑定的 C++ 实例。
  • 通过napi_unwrap获取作为调用目标的 C++ 实例
  • 当 JS 调用 C++ 类 的方法或属性时,会调用相应的 napi_callback C++ 函数。对于实例回调,napi_unwrap获取作为调用目标的 C++ 实例 。
    在这里插入图片描述

6、napi_create_reference 和 napi_get_reference_value、napi_delete_reference

napi_create_reference 用于创建对 JavaScript 对象的引用。这个引用可以用于在后续的 NAPI 调用中保持对象的生命周期,即使在对象不再被 JavaScript 代码直接引用时也不会被垃圾回收。当你在 C/C++ 代码中使用 NAPI 与 JavaScript 代码交互时,你可能需要在多个地方使用同一个 JavaScript 对象。为了确保这个对象在这些地方都被有效引用,你可以使用 napi_create_reference 来创建一个持久化的引用。这个引用可以通过一个整数值(通常称为引用句柄)来标识和操作。

napi_create_reference 函数的原型如下:

napi_status napi_create_reference(napi_env env, napi_value object, uint32_t initial_refcount, napi_ref* result);

参数说明:

  • env:指向当前环境的指针。
  • object:要创建引用的 JavaScript 对象。
  • initial_refcount:引用的初始引用计数。通常设置为 1,表示创建一个新引用。
  • result:指向 napi_ref 的指针,成功创建引用后,该位置将存储新引用的句柄。
#include <napi.h>napi_value CreateObject(napi_env env, napi_callback_info info) {// 创建一个新的 JavaScript 对象napi_value object;napi_create_object(env, &object);// 创建一个持久化的引用napi_ref ref;napi_create_reference(env, object, 1, &ref);// 这里可以将 ref 用于后续的调用,以便在需要时重新获取对象// 返回创建的对象return object;
}napi_value UseObjectReference(napi_env env, napi_callback_info info) {// 假设我们有一个有效的引用句柄napi_ref ref;// 从引用句柄获取对象napi_value object;napi_get_reference_value(env, ref, &object);// 使用对象...return nullptr;
}

使用 napi_create_reference 和 napi_get_reference_value 可以在 NAPI 函数之间共享和持久化 JavaScript 对象的引用,这在处理异步操作或跨多个调用共享资源时非常有用。需要注意的是,创建引用后,你需要负责管理引用的生命周期,包括在适当的时候使用 napi_delete_reference 来删除引用,以避免内存泄漏。

  • napi_get_reference_value() : 从napi_ref引用对象中取得napi_value
  • napi_delete_reference() :删除napi_ref引用对象

7、napi_set_named_property

用于在 JavaScript 对象上设置一个命名属性的值。napi_set_named_property 函数的原型如下:

napi_status napi_set_named_property(napi_env env,napi_value object,const char16_t* property_name,napi_value value);

参数说明:

  • env:指向当前 NAPI 环境的指针。
  • object:要设置属性的 JavaScript 对象。
  • property_name:一个以 UTF-16 编码的字符串,表示要设置的属性名。
  • value:要设置的属性值的 napi_value。
#include <napi.h>napi_value SetObjectProperty(napi_env env, napi_callback_info info) {// 创建一个 JavaScript 对象napi_value obj;napi_create_object(env, &obj);// 创建一个属性值napi_value propValue;napi_create_string_utf8(env, "Hello, World!", NAPI_OK, &propValue);// 设置对象的属性const char16_t* propertyName = "exampleProperty";napi_status status = napi_set_named_property(env, obj, propertyName, propValue);if (status != napi_ok) {// 处理错误return nullptr;}// 返回创建的对象return obj;
}

SetObjectProperty 函数首先创建了一个空的 JavaScript 对象,然后创建了一个字符串值作为属性值。最后,使用 napi_set_named_property 函数将这个值设置为对象的 exampleProperty 属性。napi_set_named_property 是 NAPI 中用于对象属性操作的重要函数之一,它使得 C/C++ 代码能够动态地修改 JavaScript 对象的状态。

8、napi_define_properties

用于在构造函数初始化时定义一个对象的属性和方法。这个函数允许你一次性定义多个属性,而不是在运行时逐个设置。
napi_define_properties 函数的原型如下:

napi_status napi_define_properties(napi_env env,napi_value object,size_t property_count,const napi_property_descriptor* properties);

参数说明:

  • env:指向当前 NAPI 环境的指针。
  • object:要定义属性的 JavaScript 对象。
  • property_count:要定义的属性数量。
  • properties:指向一个 napi_property_descriptor 数组的指针,该数组描述了要定义的属性。
  • napi_property_descriptor 结构体用于描述每个属性,其原型如下:
typedef struct {const char* name;             // 属性或方法的名称napi_value getter;             // 获取器函数,如果属性是只读的,则设置为 NULLnapi_value setter;             // 设置器函数,如果属性是只写的,则设置为 NULLnapi_value method;            // 方法函数,如果属性不是方法,则设置为 NULLnapi_value enum_value;        // 枚举值,通常设置为 NULLnapi_value default_value;      // 默认值,通常设置为 NULL
} napi_property_descriptor;

MyObjectConstructor 函数创建了一个新的 JavaScript 函数 MyObject,并使用 napi_define_properties 定义了它的静态属性 staticProperty 和静态方法 staticMethod。MyObjectMethod 是对象的方法,而 MyStaticMethod 是静态方法。napi_define_properties 函数通常在模块初始化或构造函数中使用,用于定义类原型或对象的属性和方法。

#include <napi.h>
napi_value MyObjectConstructor(napi_env env, napi_callback_info info) {// 创建一个新的 JavaScript 对象napi_value cons;napi_create_function(env, "MyObject", 0, MyObjectMethod, NULL, &cons);// 定义属性和方法napi_property_descriptor properties[] = {{"staticProperty", NULL, NULL, NULL, NULL, NULL},{"staticMethod", NULL, NULL, MyStaticMethod, NULL, NULL}};// 使用 napi_define_properties 定义属性和方法napi_status status = napi_define_properties(env, cons, sizeof(properties) / sizeof(properties[0]), properties);if (status != napi_ok) {// 处理错误return nullptr;}return cons;
}napi_value MyObjectMethod(napi_env env, napi_callback_info info) {// 实现对象的方法// ...return nullptr;
}napi_value MyStaticMethod(napi_env env, napi_callback_info info) {// 实现静态方法// ...return nullptr;
}

napi_define_properties 和 napi_set_named_property 都是 Node.js API (NAPI) 中用于操作 JavaScript 对象属性的函数。而napi_define_properties 通常在构造函数或模块初始化时使用,用于定义对象的多个属性和方法。接受一个属性描述符数组,可以一次性定义多个属性。使用 napi_define_properties 定义的属性会成为对象的原型属性,这意味着它们会被对象及其所有实例继承。它是在对象创建时调用的,用于设置对象的初始属性和方法;而napi_set_named_property 用于在运行时动态地设置或修改 JavaScript 对象的单个属性。接受对象、属性名和属性值作为参数;使用 napi_set_named_property 设置的属性是直接属性,它不会成为对象原型的一部分,也不会被对象的实例继承。它可以在任何时候调用,用于更新或添加对象的属性。

9、napi_get_cb_info从napi_callback_info类型的参数中得到回调的参数等数据

用于获取传递给异步回调或定时器回调的附加数据,通常在异步操作的完成回调中使用,以便访问在异步操作开始时附加到回调中的 NAPI 回调信息。napi_get_cb_info 函数的原型如下:

napi_status napi_get_cb_info(napi_env env,napi_callback_info info,size_t* argc,napi_value* argv,napi_value* this_arg,napi_async_context* async_context);

参数说明:

  • env:指向当前 NAPI 环境的指针。
  • info:传递给回调的 napi_callback_info。
  • argc:指向一个 size_t 的指针,用于接收回调中的参数数量。
  • argv:指向一个 napi_value 数组的指针,该数组将被填充回调中的参数。
  • this_arg:指向一个 napi_value 的指针,用于接收回调中的 this 指针。
  • async_context:指向一个 napi_async_context 的指针,用于接收异步操作的上下文信息。
napi_value MyAsyncCallback(napi_env env, napi_callback_info info) {// 获取回调信息size_t argc;napi_value argv[1];napi_value this_arg;napi_async_context async_context;// 使用 napi_get_cb_info 获取回调的参数和上下文napi_status status = napi_get_cb_info(env, info, &argc, argv, &this_arg, &async_context);if (status != napi_ok) {// 处理错误return nullptr;}// 使用 argc, argv, this_arg 和 async_context 进行后续操作// ...return nullptr;
}

napi_callback_info 中取出 JS 调用时传入的所有参数,并调用 napi 方法将其从 napi 数据类型的值 napi_value 转换成 native 数据类型的值argc为传入参数个数,argv为传入参数数组,此时参数的类型都为napi_value。

10、napi_typeof函数获取入参的实际类型

用于获取给定 napi_value 的类型信息,napi_typeof 函数的原型如下:

napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result);
  • env:指向当前 NAPI 环境的指针。
  • value:要检查类型的 napi_value。
  • result:指向 napi_valuetype 变量的指针,该变量将接收表示 value 类型的枚举值。
    napi_valuetype 枚举包含了多种类型,例如 napi_undefined、napi_null、napi_boolean、napi_number、napi_string、napi_symbol、napi_object、napi_function 等
napi_value CheckValueType(napi_env env, napi_callback_info info) {// 假设我们有一个 napi_value 需要检查类型napi_value value;napi_get_cb_info(env, info, NULL, &value, NULL, NULL);// 检查值的类型napi_valuetype type;napi_typeof(env, value, &type);// 根据类型进行不同的操作switch (type) {case napi_undefined:// 处理未定义类型的值break;case napi_null:// 处理空类型的值break;case napi_number:// 处理数字类型的值break;case napi_string:// 处理字符串类型的值break;// 其他类型的处理...default:// 未知类型的处理break;}return nullptr;
}

11、napi_get_value_string_utf8方法将napi_string转换char*

napi_status napi_get_value_string_utf8(napi_env env,napi_value value,char* buf,size_t bufsize,size_t* result);

12、 napi_module_register

用于注册一个 NAPI 模块。这个函数在模块的初始化代码中被调用,以便将模块的导出函数和属性添加到 Node.js 的全局对象上,从而使得这些函数和属性可以被 JavaScript 代码访问和使用。
napi_module_register 函数的原型如下:

napi_status napi_module_register(napi_env env,napi_object reference,napi_value (*module_init)(napi_env, napi_value),napi_value* result);

参数说明:

  • env:指向当前 NAPI 环境的指针。
  • reference:一个 napi_object,包含了模块的导出对象。这个对象通常是通过调用 napi_create_object 创建的,并且可以包含多个属性和方法。
  • module_init:指向一个函数的指针,该函数用于初始化模块。这个函数将被调用,并且应该返回模块的导出对象。
  • result:指向一个 napi_value 的指针,用于接收注册操作的结果。如果注册成功,这个值将是模块的导出对象。

未完待续…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/50286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统模块时序图的重要性:解锁系统模块交互的全景视图

在复杂的系统开发中,理解和管理不同模块之间的交互是成功的关键。时序图是一种有效的工具,可以帮助我们清晰地展示这些交互,提升设计和开发的效率。本文将深入探讨系统模块之间的时序图,并通过实例展示其实际应用。 1. 什么是系统模块之间的时序图? 系统模块之间的时序图…

Layui表格向下滑动时表头固定悬浮

记录&#xff1a;Layui表格向下滑动时表头固定悬浮 使用table的height参数&#xff1a; 示例 //“方法级渲染”配置方式 table.render({ //其它参数在此省略height: 315 //固定值 }); table.render({ //其它参数在此省略height: full-20 //高度最大化减去差值 }); 等价于&am…

项目的小结

1.实现实时聊天 1.服务端建立一个ConcurrentHashMap<> 用来存储在线用户&#xff0c;用户账号和socket然后&#xff0c;如果有个人发了信息&#xff0c;就去数据库中查询&#xff0c;然后根据这个在线用户进行传递信息 服务端框架&#xff1a; public class ServerMain {…

git sendemail使用

教程参考&#xff1a; git-send-email - 以电子邮件形式发送补丁集 1、安装git-email 2、配置 SMTP 服务器 git config --global sendemail.smtpserver smtp.163.com git config --global sendemail.smtpserverport 465 git config --global sendemail.smtpuser xxxxxx163.c…

Hyperledger Fabric 网络体验 - 网络启动过程概览

进入fabric-samples/test-network目录&#xff0c;执行指令&#xff1a; ./network.sh up -i 2.5执行完指令能看到fabric已经启动。 作为第一次Fabric网络体验&#xff0c;网络启动主要包含三个操作&#xff0c;分别是生成配置文件、启动网络和操作网络。 配置文件 使用cr…

传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 论文链接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1076633223003537?__cf_chl_rt_tkJ9Aipfxyk5d.leu48P20ePFNd4B2aunaSmzVpXCg.7g-1721292386-0.0.1.1-6249 论文概述 今天我们把视线…

【系统架构设计师】十八、信息系统架构设计理论与实践②

目录 四、企业信息系统的总体框架 4.1 战略系统 4.2 业务系统 4.3 应用系统 4.4 企业信息基础设施 4.5 业务流程重组BPR 4.6 业务流程管理BPM 五、信息系统架构设计方法 5.1 行业标准的体系架构框架 5.2 架构开发方法 5.3 信息化总体架构方法 5.4 信息化建设生命周…

Golang | Leetcode Golang题解之第290题单词规律

题目&#xff1a; 题解&#xff1a; func wordPattern(pattern string, s string) bool {word2ch : map[string]byte{}ch2word : map[byte]string{}words : strings.Split(s, " ")if len(pattern) ! len(words) {return false}for i, word : range words {ch : patt…

【知识分享】MIPI C-PHY 互连技术参数定义

目录 0 概述 1 Interconnect Specifications 1.1 Differential Insertion Loss 1.2 Differential Reflection Loss 1.3 Common-Mode Reflection Loss 1.4 Intra-Lane Cross Coupling 1.5 Mode-Conversion Loss 1.6 Inter-Lane Static Skew 2 Driver and Receiver Char…

好的STEM编程语言有哪些?

STEM是科学&#xff08;Science&#xff09;&#xff0c;技术&#xff08;Technology&#xff09;&#xff0c;工程&#xff08;Engineering&#xff09;&#xff0c;数学&#xff08;Mathematics&#xff09;四门学科英文首字母的缩写&#xff0c;STEM教育简单来说就是在通过在…

【管控业财一体化】

1. 引言 大型集团在现代企业管理中扮演着举足轻重的角色&#xff0c;其管控业财一体化解决方案是实现企业高效运营的关键。随着数字化转型的加速&#xff0c;业财一体化不再局限于财务与业务流程的简单融合&#xff0c;而是向着更深层次的数据驱动、智能化决策和价值创造方向发…

SpringMVC中的常用注解

目录 SpringMVC的定义 SpringMVC的常用注解 获取Cookie和Session SpringMVC的定义 Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc)&#xff0c;但它…

百某应JS逆向

https://ying.baichuan-ai.com/ 目录 一、发起提问 二、观察发现有两个加密参数&#xff1a;X-Bc-Sig和X-Bc-Ts ​三、观察JS调用栈 四、从JS中搜索 X-Bc-Sig和X-Bc-Ts 五、断点并分析参数的生成方式 六、分析入参 七、发现关键的o方法调用了一个i()方法 八、验证结果 …

前后端项目打包对比——关于Spring Boot Maven Plugin配置的问题

Spring Boot Maven Plugin 配置详解 Spring Boot Maven Plugin 配置详解1. 添加插件到 pom.xml2. 插件配置2.1 基本配置2.2 配置参数详解默认行为说明简单配置示例为什么这样的配置能工作&#xff1f;进一步说明 2.3 高级配置 3. 使用插件打包应用程序3.1 打包成 JAR 文件3.2 打…

ElasticSearch(六)— 全文检索

一、match系列查询 前面讲到的query中的查询&#xff0c;都是精准查询。可以理解成跟在关系型数据库中的查询类似。match系列的查询&#xff0c;是全文检索的查询。会通过分词进行评分&#xff0c;匹配&#xff0c;再返回搜索结果。 1.1 match 查询 "query": {&qu…

c++笔记4

目录 深度优先搜索DFS DFS的复杂度 DFS与递归 递归与暴力枚举 递归树 DFS与栈 DFS的搜索剪枝 搜索剪枝与优化 可行性剪枝 最优化剪枝 减少等效的分支 优化搜索顺序 搜索的记忆化 搜索的复杂度 大多时候&#xff0c;搜索的复杂度都是指数级的。各种剪枝方案&#…

Flink 技术与应用(一)

Flink技术与应用&#xff08;初级篇&#xff09; 起源 Apache Flink 是一个开源的大数据处理框架&#xff0c;其起源可以追溯到一个名为 Stratosphere 的研究项目&#xff0c;旨在建立下一代大数据分析引擎&#xff0c;2010 年&#xff0c;从 Stratosphere 项目中分化出了 Fl…

「Unity3D」场景中的距离单位Unit与相关设置PixelsToUnits、PixelsPerUnit

GameObject在场景的位置Position&#xff0c;并没有明确是什么具体单位——如&#xff1a;Transform的x、y、z&#xff0c;或RectTransform的PosX、PosY、PosZ。而RectTransform在面板上显示的Width和Height&#xff0c;也没有具体单位&#xff0c;其实并不是像素。 事实上&am…

百易云资产管理运营系统 comfileup.php 文件上传致RCE漏洞复现(XVE-2024-18154)

0x01 产品简介 百易云资产管理运营系统,是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全生命周期管理,包括资产的登记、盘点、评估、处置等多个环节,同时提供强大的运营分析功能,帮助企业优化资产配置,提升运营效率。 0x02 漏…

C++内存管理(候捷)第五讲 笔记

GNU C对allocators的描述 new_allocator 和malloc_allocator&#xff0c;它们都没有特别的动作&#xff0c;无非底部调用operator new和malloc。它们没有用内存池 区别&#xff1a;::operator new是可重载的 智能型的allocator&#xff0c;使用内存池&#xff0c;分一大块然后…