环境
unity 2022.3.62f1
Puerts_V8_2.2.2_16kb
RuntimeError: null function or function signature mismatch
打包webgl后,运行报错:
Invoking error handler due to
RuntimeError: null function or function signature mismatch
at pesapi_on_class_not_found (export_browser_1ae4ad.wasm.gz:0x85483c)
at VideoClipMedia::JobEntryPointInternal(browser/void (*)(void*), void*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at invoke_vi (export_browser_f0532d.framework.js.gz:10:439456)
at puerts::InitialPapiEnvRef(browser/pesapi_ffi*, pesapi_env_ref__*, Il2CppObject*, Il2CppReflectionMethod*, Il2CppReflectionMethod*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at JsEnv__ctor_m721E14524F762EED47C03E0096E54C27589FA674 (export_browser_1ae4ad.wasm.gz:0x8ef111)
at MainEnv_Get_mAC2BF76F4EABB1D291F740413E6F3E92ABC9A8AA (export_browser_1ae4ad.wasm.gz:0x913f4e)
at JVM_Init_mF36761B3907926989F056C942227057D26B0F877 (export_browser_1ae4ad.wasm.gz:0x91ce44)
at root_webgl_ExecuteJS_m2B80BE468922838185546A0E5A5916010F65178A (export_browser_1ae4ad.wasm.gz:0x922d99)
at root_webgl_OnCheckEnd_mE2B188B0793C53430E29B7C0748E28489817DC26 (export_browser_1ae4ad.wasm.gz:0x922d1b)
at AssetRequest_EndLoad_mCD188F843011FBC820B0B74E492F4C17FABA0893 (export_browser_1ae4ad.wasm.gz:0x93b65a)
at ResLoader_Update_m70FFEF1A8E0CDC5AC632FC54132FCBA0C0DAC786 (export_browser_1ae4ad.wasm.gz:0x943106)
at RuntimeInvoker_TrueVoid_t4861ACF8F4594C3437BB48B6E56783494B843915(browser/void (*)(), MethodInfo const*, void*, void**, void*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at il2cpp::vm::Runtime::InvokeWithThrow(browser/MethodInfo const*, void*, void**) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at dynCall_iiii (export_browser_1ae4ad.wasm.gz:0x19d32cf)
at invoke_iiii (export_browser_f0532d.framework.js.gz:10:439605)
at il2cpp::vm::Runtime::Invoke(browser/MethodInfo const*, void*, void**, Il2CppException**) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at il2cpp_runtime_invoke (export_browser_1ae4ad.wasm.gz:0xb2963)
at scripting_method_invoke(browser/ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at ScriptingInvocation::Invoke(browser/ScriptingExceptionPtr*, bool) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at MonoBehaviour::CallUpdateMethod(browser/int) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at MonoBehaviour::Update(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at BehaviourManager::Update(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at InitPlayerLoopCallbacks(browser/)::UpdateScriptRunBehaviourUpdateRegistrator::Forward() (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at ExecutePlayerLoop(browser/NativePlayerLoopSystem*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at ExecutePlayerLoop(browser/NativePlayerLoopSystem*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at MainLoop(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_1ae4ad.wasm.gz)
at dynCall_v (export_browser_1ae4ad.wasm.gz:0x19d3301)
at browserIterationFunc (export_browser_f0532d.framework.js.gz:10:247653)
at callUserCallback (export_browser_f0532d.framework.js.gz:10:201225)
at Object.runIter (export_browser_f0532d.framework.js.gz:10:202465)
at Browser_mainLoop_runner (export_browser_f0532d.framework.js.gz:10:200761)
按理说,这个pesapi_on_class_not_found定义在Assets\webgl\upm\Runtime\Plugins\WebGL\puerts.jslib中:

image.png
理应注册到
exportDLL中,但实际查看打包后的framework.js:
image.png
只有部分方法存在,搜索
please find some way to load puerts-runtime.js看到只匹配了40个
image.png
而
puerts.jslib中明显不止这么多。修改打包后的
puerts-runtime.js,找到这部分代码:
n.global.wxRequire = n.global.require, n.global.PuertsWebGL = {
inited: !1,
debug: !1,
Init(e) {
}
}
把其中的debug: !1改为debug: true,得到日志
WebGL DLL:SetLogCallback
WebGL DLL:GetRegsterApi
WebGL DLL:CreateJSEngine
WebGL DLL:GetLibBackend
WebGL DLL:GetWebGLFFIApi
WebGL DLL:GetWebGLPapiEnvRef
WebGL DLL:pesapi_open_scope_placement_js
WebGL DLL:pesapi_set_env_private_js
WebGL DLL:pesapi_create_function_js
WebGL DLL:pesapi_create_function_js
WebGL DLL:pesapi_global_js
WebGL DLL:pesapi_set_property_js
WebGL DLL:pesapi_set_property_js
这些函数都call成功了。现在问题就是pesapi_on_class_not_found这个函数不知道为何没有打包到framework.js中。这想来有种被剔除了的感觉。
于是统计了一下,merge成功的函数一共39个:
GetLibBackend
CreateJSEngine
DestroyJSEngine
LowMemoryNotification
IdleNotificationDeadline
RequestMinorGarbageCollectionForTesting
RequestFullGarbageCollectionForTesting
CreateInspector
InspectorTick
LogicTick
SetLogCallback
GetWebGLFFIApi
GetWebGLPapiEnvRef
GetQjsFFIApi
GetQjsPapiEnvRef
GetRegsterApi
pesapi_create_array_js
pesapi_create_object_js
pesapi_create_function_js
pesapi_create_class_js
pesapi_native_object_to_value_js
pesapi_throw_by_string_js
pesapi_open_scope_placement_js
pesapi_has_caught_js
pesapi_get_exception_as_string_js
pesapi_close_scope_placement_js
pesapi_create_value_ref_js
pesapi_release_value_ref_js
pesapi_get_value_from_ref_js
pesapi_get_property_js
pesapi_set_property_js
pesapi_get_private_js
pesapi_set_private_js
pesapi_get_property_uint32_js
pesapi_set_property_uint32_js
pesapi_call_function_js
pesapi_eval_js
pesapi_global_js
pesapi_set_env_private_js
没有merge的则有77个:
GetLibVersion
GetApiLevel
CreateJSEngineWithExternalEnv
SetGlobalFunction
GetLastExceptionInfo
SetGeneralDestructor
Eval
ClearModuleCache
GetModuleExecutor
GetJSObjectValueGetter
GetJSStackTrace
_RegisterClass
RegisterStruct
RegisterFunction
RegisterProperty
ReturnClass
ReturnObject
ReturnNumber
ReturnString
ReturnBigInt
ReturnBoolean
ReturnDate
ReturnNull
ReturnFunction
ReturnJSObject
ReturnArrayBuffer
ReturnCSharpFunctionCallback
ReturnCSharpFunctionCallback2
GetTypeIdFromValue
SetNumberToOutValue
SetDateToOutValue
SetStringToOutValue
SetBooleanToOutValue
SetBigIntToOutValue
SetObjectToOutValue
SetNullToOutValue
SetArrayBufferToOutValue
ThrowException
PushNullForJSFunction
PushDateForJSFunction
PushBooleanForJSFunction
PushBigIntForJSFunction
PushStringForJSFunction
__PushStringForJSFunction
PushNumberForJSFunction
PushObjectForJSFunction
PushJSFunctionForJSFunction
PushJSObjectForJSFunction
PushArrayBufferForJSFunction
SetPushJSFunctionArgumentsCallback
InvokeJSFunction
GetFunctionLastExceptionInfo
ReleaseJSFunction
ReleaseJSObject
GetResultType
GetNumberFromResult
GetDateFromResult
GetStringFromResult
GetBooleanFromResult
ResultIsBigInt
GetBigIntFromResult
GetObjectFromResult
GetTypeIdFromResult
GetFunctionFromResult
GetJSObjectFromResult
GetArrayBufferFromResult
ResetResult
DestroyInspector
TerminateExecution
pesapi_alloc_property_descriptors
pesapi_define_class
pesapi_get_class_data
pesapi_on_class_not_found
pesapi_set_method_info
pesapi_set_property_info
pesapi_trace_native_object_lifecycle
pesapi_get_array_length_js
果不其然,以GetLibVersion为例,确实和code striping有关系:

image.png
这个接口并没有被显式引用。
而看看
GetLibBackend则是被引用了:
image.png
于是我试试看把stripe code关掉,重新打包再试,还是一样的报错。由此可见以上分析并不正确。
回头再看看报错堆栈,报错是报在wasm.gz里,这么应该是C#或C++里面报错。回头看看
puerts::InitialPapiEnvRef所在的project\Assets\Gen\Plugins\puerts_il2cpp\Puerts_il2cpp.cpp,这个文件是wrap生成的。仔细查看生成wrap代码的源码,发现webgl模式下有所区别:
image.png
所以真正的原因是我wrap的代码是在非webgl模式下wrap的,生成的puerts native plugins不适用于webgl。unity切到webgl后重新wrap解决此问题。
又一次 null function or function signature mismatch
过几天,在一次构建版本后,又一次遇到类似的报错:
Uncaught RuntimeError: null function or function signature mismatch
at JsEnv__ctor_m721E14524F762EED47C03E0096E54C27589FA674 (export_browser_c26325.wasm.gz:0x6bfd9c)
at MainEnv_Get_mAC2BF76F4EABB1D291F740413E6F3E92ABC9A8AA (export_browser_c26325.wasm.gz:0x6ce683)
at JVM_Init_mF36761B3907926989F056C942227057D26B0F877 (export_browser_c26325.wasm.gz:0x76f2af)
at root_webgl_ExecuteJS_m2B80BE468922838185546A0E5A5916010F65178A (export_browser_c26325.wasm.gz:0x774c89)
at root_webgl_OnCheckEnd_mE2B188B0793C53430E29B7C0748E28489817DC26 (export_browser_c26325.wasm.gz:0x774c0b)
at AssetRequest_EndLoad_mCD188F843011FBC820B0B74E492F4C17FABA0893 (export_browser_c26325.wasm.gz:0x790db8)
at ResLoader_Update_m70FFEF1A8E0CDC5AC632FC54132FCBA0C0DAC786 (export_browser_c26325.wasm.gz:0x79822c)
at RuntimeInvoker_TrueVoid_t4861ACF8F4594C3437BB48B6E56783494B843915(browser/void (*)(), MethodInfo const*, void*, void**, void*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at il2cpp::vm::Runtime::InvokeWithThrow(browser/MethodInfo const*, void*, void**) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at dynCall_iiii (export_browser_c26325.wasm.gz:0x199c1fa)
at invoke_iiii (export_browser_2e2702.framework.js.gz:10:534337)
at il2cpp::vm::Runtime::Invoke(browser/MethodInfo const*, void*, void**, Il2CppException**) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at il2cpp_runtime_invoke (export_browser_c26325.wasm.gz:0xca8ca)
at scripting_method_invoke(browser/ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at ScriptingInvocation::Invoke(browser/ScriptingExceptionPtr*, bool) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at MonoBehaviour::CallUpdateMethod(browser/int) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at MonoBehaviour::Update(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at BehaviourManager::Update(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at InitPlayerLoopCallbacks(browser/)::UpdateScriptRunBehaviourUpdateRegistrator::Forward() (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at ExecutePlayerLoop(browser/NativePlayerLoopSystem*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at ExecutePlayerLoop(browser/NativePlayerLoopSystem*) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at MainLoop(browser/) (http://builder.fygame.com:8484/res/sjqy_develop/browser/Build/export_browser_c26325.wasm.gz)
at dynCall_v (export_browser_c26325.wasm.gz:0x199c22c)
at browserIterationFunc (export_browser_2e2702.framework.js.gz:10:378435)
at callUserCallback (export_browser_2e2702.framework.js.gz:10:270603)
at Object.runIter (export_browser_2e2702.framework.js.gz:10:271843)
at Browser_mainLoop_runner (export_browser_2e2702.framework.js.gz:10:270139)
这一次报错和上次类似又有所不同。一开始还以为又是wrap的问题,可在webgl模式下重新wrap后,问题依旧。将Assets\Gen\Plugins\puerts_il2cpp的内容还原到上一次没有报错的状态,发现确实有所变化。查看生成wrap代码的源码,发现有一段读取小游戏配置的代码:

image.png
这里当小游戏里的设置和Player Setting的设置冲突时,优先使用小游戏的设置。于是想起来了,前两天安装了小游戏插件!小游戏插件里IL2CppOptimizeSize默认是OptimizeSize,而Player Setting里我设置的OptimizeSpeed。把两者统一,这个报错就解决了。