native关键字可用于声明native函数。
native函数的定义来源于某个dll模块或amxx插件,这里不讨论dll模块。
主插件需使用register_native函数将native函数与某个公共函数互相绑定。
其它插件调用native函数时,等于调用其绑定的公共函数。
#include <amxmodx>
public plugin_natives()
{
// 将native函数TestFunc绑定到公共函数@TestFunc
register_native("TestFunc", "@TestFunc");
}
public plugin_precache()
{
register_plugin("测试插件1", "1.0.0", "插件作者");
}
// 参数1:来访插件的索引,参数2:来访插件送来多少个参数
@TestFunc(pluginId, paramCount)
{
server_print("[AMXX] 随便做点什么 !");
}
#if (defined(_testplugin_included))
#endinput
#endif
#define _testplugin_included
// 声明native函数:该函数与主插件的公共函数@TestFunc函数互相绑定
native TestFunc();
#include <amxmodx>
#include <testplugin> // 假设主插件提供的是testplugin.inc文件,引用它
public plugin_precache()
{
register_plugin("测试插件2", "1.0.0", "插件作者");
// 调用TestFunc函数,等于调用主插件的@TestFunc函数
TestFunc();
}
用户需要自行阅读这register_native函数相关注释。
/// native函数错误
#define AMX_ERR_NATIVE 10
/// 内存访问错误
#define AMX_ERR_MEMACCESS 5
/// 无理由错误(在native函数中无效)
#define AMX_ERR_NONE 0
/// 索引越界
#define AMX_ERR_BOUNDS 4
/// 栈错误
#define AMX_ERR_STACKERR 3
/// 栈空间不足
#define AMX_ERR_STACKLOW 7
/// 堆空间不足
#define AMX_ERR_HEAPLOW 8
/// 除法错误
#define AMX_ERR_DIVIDE 11
/// 找不到函数
#define AMX_ERR_NOTFOUND 19
/// 参数错误
#define AMX_ERR_PARAMS 25
/// 未知错误
#define AMX_ERR_GENERAL 27
/**
* 将native和public函数互相绑定。
*
* @note 此函数只能在plugin_natives函数内运行,一个native函数只能绑定一次,重新绑定没有任何效果。
*
* @note native函数不该自己调用自己,会出问题。
*
* @param name native函数名称
* @param handler public函数名称,函数内部可使用log_error函数抛出错误
* @param style public函数风格:
* style参数为0时,应该像这样声明public函数的参数:
* public native_handler(plugin_id, argc)
* plugin_id - 来访插件的索引
* argc - 来访插件送来多少个参数
* public函数内部应该使用下列函数访问参数:
* get_string/set_string/get_param/get_param_f/get_param_byref/get_float_byref/
* set_param_byref/set_float_byref/get_array/get_array_f/set_array/set_array_f
* style参数值1已被弃用,因为可能会出问题,插件不应该使用。
* style参数为1时,public函数签名应该与native函数签名完全一致。
* 并且public函数内部应该使用param_convert函数处理每个按引用传递的参数
*
* @noreturn
* @error handler参数所指public函数不存在。
*/
native register_native(const name[], const handler[], style = 0);
/**
* 记录错误日志,并在退出public函数后,让来访插件跳转到AMXX调试器。
* 让来访插件对native函数的调用失败,抛出错误。
*
* @note 调用log_error函数的是定义native和public函数的插件,触发错误的是调用native函数的插件
*
* @note 执行此函数并不会立即抛出错误,而是在退出public函数后抛出错误
*
* @param error 错误码,详情查阅amxconst.inc文件中名称以AMX_ERR_开头的宏常量
* @param fmt 需要录入日志文件的文本,允许使用格式占位符%b %c %d %i %u %f %X %x %a %s %L %l %N %n %% %
* 格式占位符表示将后续参数转换为某一样式的字符串,填充到自身位置。
* %b 需要1个单值参数,二进制样式。
* %c 需要1个单值参数,字符样式。
* %d 和 %i 完全相同,需要1个单值参数,十进制样式。
* %u 需要1个单值参数,无符号十进制样式。
* %f 需要1个单值参数,浮点数样式。
* %X 需要1个单值参数,大写十六进制样式。
* %x 需要1个单值参数,小写十六进制样式。
* %a 需要1个单值参数(字符串指针),字符串样式。
* %s 需要1个数组参数(字符串)。不转换。
* %L 需要1个单值参数(LANG_SERVER/LANGE_PLAYER/玩家实体索引)和1个数组参数(预设的可翻译字符串)。
* LANG_SERVER表示"使用服务端设定的语言"。
* LANGE_PLAYER表示"显示给谁就使用谁设定的语言"。
* 玩家实体索引表示"使用索引所指玩家设定的语言"。
* 预设的可翻译字符串来自register_dictionary函数。
* 将字符串转换为翻译后的内容。
* %l 需要1个数组参数(预设的可翻译字符串),显示给谁就使用谁设定的语言,将字符串转换为翻译后的内容。
* %N 需要1个单值参数(玩家实体索引),"玩家名称<队伍名称>"样式。
* %n 需要1个单值参数(玩家实体索引),转换为玩家名称。
* %% 不需要参数,而是将自身转换为 % 字符。
* % 不需要参数,而是会被删除。
* @param ... 这是可变参数,允许输入输出任何类型的参数。但这里要求按照顺序填写格式占位符所需的参数
*
* @noreturn
*/
native log_error(error, const fmt[], any:...);
/**
* 处理native函数的传引用参数,使其能正常工作。
*
* @deprecated 绑定native函数时,若style参数为1,应该改为0,并且不需要处理传引用参数
*
* @note 绑定native函数时,若style参数为1,则必须处理传引用参数
* @note 注意:数组、字符串、带有&修饰符的单值参数,都是按引用传递
*
* @param num 需处理的参数号码,从1开始
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为0。
*/
native param_convert(num);
/**
* 复制native函数的字符串参数。
*
* @param param 参数号码,从1开始
* @param dest 输出字符串参数的副本
* @param maxlen 最多输出多少个字符(不包括终止符)
*
* @return 实际输出多少个字符(不包括终止符)
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native get_string(param, dest[], maxlen);
/**
* 更改native函数的字符串参数。
*
* @param param 参数号码,从1开始
* @param dest 新字符串
* @param maxlen 最多从新字符串复制多少个字符(不包括终止符)
*
* @return 实际复制多少个字符(不包括终止符)
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native set_string(param, dest[], maxlen);
/**
* 复制native函数按值传递的单值参数。
*
* @param param 参数号码,从1开始
*
* @return 参数值,若有需要,使用标签覆盖表达式更改标签
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native get_param(param);
/**
* 复制native函数按值传递的单值参数,并用Float标签覆盖_标签。
*
* @param param 参数号码,从1开始
*
* @return 参数值
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native Float:get_param_f(param);
/**
* 复制native函数按引用传递的单值参数。
*
* @param param 参数号码,从1开始
*
* @return 参数值,若有需要,使用标签覆盖表达式更改标签
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native get_param_byref(param);
/**
* 复制native函数按引用传递的单值参数,并用Float标签覆盖_标签。
*
* @param param 参数号码,从1开始
*
* @return 参数值
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native Float:get_float_byref(param);
/**
* 更改native函数按引用传递的单值参数。
*
* @param param 参数号码,从1开始
* @param value 新值,若拥有any或_以外的标签,需附带标签覆盖表达式
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native set_param_byref(param, value);
/**
* 更改native函数按引用传递的单值参数。
*
* @param param 参数号码,从1开始
* @param value 带有Float标签的新值(标签是插件独享,编译时删除的,各插件同名标签id不同,并不能证明数值真的是浮点数)
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native set_float_byref(param, Float:value);
/**
* 获取native函数的一维数组参数。
*
* @param param 参数号码,从1开始
* @param dest 输出参数值,若有any或_以外的标签,需使用标签覆盖表达式
* @param size 需要输出多少个元素
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native get_array(param, dest[], size);
/**
* 获取native函数的一维数组参数。
*
* @param param 参数号码,从1开始
* @param dest 输出参数值,若有Float以外的标签,需使用Float:标签覆盖表达式
* @param size 需要输出多少个元素
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native get_array_f(param, Float:dest[], size);
/**
* 更改native函数的一维数组参数。
*
* @param param 参数号码,从1开始
* @param source 新数组,若有any或_以外的标签,需使用标签覆盖表达式
* @param size 从新数组复制多少个元素
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native set_array(param, const source[], size);
/**
* 更改native函数的一维数组参数。
*
* @param param 参数号码,从1开始
* @param source 新数组,若有Float以外的标签,需使用Float:标签覆盖表达式
* @param size 从新数组复制多少个元素
*
* @noreturn
* @error 在native函数绑定的public函数外使用;
* 绑定public函数时style参数为1。
*/
native set_array_f(param, const Float:source[], size);