标签:style blog http io color ar 使用 for sp
1> erlang:function_exported(crypto,start,0). false 2> crypto:start(). ok 3> erlang:function_exported(crypto,start,0). true
-module(test). -compile(export_all). function_exported(Module, Function, Arity) -> case erlang:module_loaded(Module) of true -> next; _ -> code:load_file(Module) end, erlang:function_exported(Module, Function, Arity).另外,如果模块被改成bif也无法判断了。不过这倒不用太过担心,我们自己写的函数都不会是bif
BIF_RETTYPE function_exported_3(BIF_ALIST_3) { if (is_not_atom(BIF_ARG_1) || is_not_atom(BIF_ARG_2) || is_not_small(BIF_ARG_3)) { BIF_ERROR(BIF_P, BADARG); } if (erts_find_function(BIF_ARG_1, BIF_ARG_2, signed_val(BIF_ARG_3), erts_active_code_ix()) == NULL) { BIF_RET(am_false); } BIF_RET(am_true); }erts_find_function实现在erts\emulator\beam\export.c中:
/* * Find the export entry for a loaded function. * Returns a NULL pointer if the given function is not loaded, or * a pointer to the export entry. * * Note: This function never returns export entries for BIFs * or functions which are not yet loaded. This makes it suitable * for use by the erlang:function_exported/3 BIF or whenever you * cannot depend on the error_handler. */ Export* erts_find_function(Eterm m, Eterm f, unsigned int a, ErtsCodeIndex code_ix) { struct export_templ templ; struct export_entry* ee; ee = hash_get(&export_tables[code_ix].htable, init_template(&templ, m, f, a)); if (ee == NULL || (ee->ep->addressv[code_ix] == ee->ep->code+3 && ee->ep->code[3] != (BeamInstr) BeamOp(op_i_generic_breakpoint))) { return NULL; } return ee->ep; }这里,export_tables是一个全局变量,还是在export.c,其中,code_ix被用来控制代码版本,有时间的话再讨论erlang热更新机制
static IndexTable export_tables[ERTS_NUM_CODE_IX]; /* Active not locked */所以,erlang:function_exported/3只是去查找导出函数的哈希表,找到返回true,没有就false
标签:style blog http io color ar 使用 for sp
原文地址:http://blog.csdn.net/mycwq/article/details/40663737