-
Notifications
You must be signed in to change notification settings - Fork 811
Open
Labels
Description
前置阅读 | Pre-reading
Puer的版本 | Puer Version
master
UE的版本 | UE Version
5.7.2
发生在哪个平台 | Platform
Editor(win)
错误信息 | Error Message
注册一个静态绑定的测试函数,携带结构体数组(FSoftObjectPath)作为参数。
其中容器注册包含了UsingContainer以及RegisterTArray,代码如下:
struct FArrayOverloadTest
{
static void TestOverload(const TArray<int>& Array)
{
UE_LOG(LogTemp, Warning, TEXT("[FArrayOverloadTest] TestOverload with array length: %d"), Array.Num());
}
static void TestOverload(const TArray<int>& Array, int Val)
{
UE_LOG(LogTemp, Warning, TEXT("[FArrayOverloadTest] TestOverload with array length: %d and value: %d"), Array.Num(), Val);
}
};
UsingContainer(TArray<FSoftObjectPath>);
struct AutoRegisterForTest
{
AutoRegisterForTest()
{
RegisterTArray(FSoftObjectPath);
puerts::DefineClass<FArrayOverloadTest>()
.Function("TestOverload", CombineOverloads(
MakeOverload(void(*)(const TArray<FSoftObjectPath>& Array), &FArrayOverloadTest::TestOverload),
MakeOverload(void(*)(const TArray<FSoftObjectPath>& Array, int), &FArrayOverloadTest::TestOverload)))
.Register();
}
}
AutoRegisterForTest _AutoRegisterForTest_;尝试在js中测试调用会失败:
import * as cpp from 'cpp';
import * as UE from 'ue';
const assetArray = UE.NewArray(UE.SoftObjectPath);
cpp.FArrayOverloadTest.TestOverload(assetArray);失败提示报错:
Puerts: Warning: (0x00000250120BE330) unhandledRejection,Error: invalid parameter!,Error: invalid parameter!
问题重现 | Bug reproduce
上述代码执行能重现问题。跟踪了一下调用栈:第一个参数在ArgumentsChecker的检查中失败了
template <std::size_t ND, typename... CArgs>
struct ArgumentsChecker<true, ND, CArgs...>
{
static bool Check(typename API::ContextType context, typename API::CallbackInfoType info)
{
// ...
// 这里失败了
if (!ArgumentChecker<API, 0, ArgsLength - ND, CArgs...>::Check(info, context))
return false;
return true;
}
};最终是IsInstanceOfCppObject中的Template里面, HasInstance的判断失败了:
bool DataTransfer::IsInstanceOf(v8::Isolate* Isolate, const void* TypeId, v8::Local<v8::Value> JsObject)
{
return JsObject->IsObject() &&
IsolateData<ICppObjectMapper>(Isolate)->IsInstanceOfCppObject(Isolate, TypeId, JsObject.As<v8::Object>());
}
bool FCppObjectMapper::IsInstanceOfCppObject(v8::Isolate* Isolate, const void* TypeId, v8::Local<v8::Object> JsObject)
{
// ...
auto ClassDefinition = FindClassByID(TypeId);
if (ClassDefinition)
{
// 能找到这个ClassDefinition和Template,但HasInstance失败了。
auto Template = GetTemplateOfClass(Isolate, ClassDefinition);
return Template->HasInstance(JsObject);
}
}似乎在UE.NewArray(UE.SoftObjectPath)去构造一个数组的时候,并没有触发GetTemplateOfClass,也没有向其中添加任何Instance。
Reactions are currently unavailable