20tab / UnrealEnginePython

Embed Python in Unreal Engine 4

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

In UE4.23,the func of "bind_event" will cause crash,how to solve this bug

BulletHermit opened this issue · comments

When I use bind_event in my python script, it will casues crash.
How to solve it or my usage is wrong?

This is my code in python script

def begin_play(self):
    self.uobject.bind_event('OnActorBeginOverlap', self.manage_overlap)
def manage_overlap(self, me, other):
    ue.print_string('overlapping ' + other.get_name())

This is the log of crash.

LoginId:fc0bca1746905f37e5068faf9afa225d
EpicAccountId:93eb976f25a3411e89f85a41a23daa15

Unhandled exception

UE4Editor_UnrealEnginePython!TMulticastScriptDelegate::TMulticastScriptDelegate()
UE4Editor_UnrealEnginePython!ue_bind_pyevent() [F:\Gayboy\branches\FightGuy_001\Plugins\UnrealEnginePython\Source\UnrealEnginePython\Private\UEPyModule.cpp:3118]
UE4Editor_UnrealEnginePython!py_ue_bind_event() [F:\Gayboy\branches\FightGuy_001\Plugins\UnrealEnginePython\Source\UnrealEnginePython\Private\UObject\UEPyObject.cpp:1522]
python27
python27
python27
python27
python27
python27
python27
python27
python27
python27
UE4Editor_UnrealEnginePython!APyCharacter::BeginPlay() [F:\Gayboy\branches\FightGuy_001\Plugins\UnrealEnginePython\Source\UnrealEnginePython\Private\PyCharacter.cpp:137]
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor
UE4Editor
UE4Editor
UE4Editor
UE4Editor
kernel32
ntdll

I have the same problem.

However, when I tried debugging, the next instruction after UEPyModule.cpp:3118 jumped to a method from Array.h:

	/**
	 * Copies data from one array into this array. Uses the fast path if the
	 * data in question does not need a constructor.
	 *
	 * @param Source The source array to copy
	 * @param PrevMax The previous allocated size
	 * @param ExtraSlack Additional amount of memory to allocate at
	 *                   the end of the buffer. Counted in elements. Zero by
	 *                   default.
	 */
	template <typename OtherElementType, typename OtherSizeType>
	void CopyToEmpty(const OtherElementType* OtherData, OtherSizeType OtherNum, SizeType PrevMax, SizeType ExtraSlack)
	{
		SizeType NewNum = OtherNum;
		checkf((OtherSizeType)NewNum == OtherNum, TEXT("Invalid number of elements to add to this array type: %llu"), (unsigned long long)NewNum);

		checkSlow(ExtraSlack >= 0);
		ArrayNum = NewNum;
		if (OtherNum || ExtraSlack || PrevMax)
		{
			ResizeForCopy(NewNum + ExtraSlack, PrevMax);
			ConstructItems<ElementType>(GetData(), OtherData, OtherNum);
		}
		else
		{
			ArrayMax = 0;
		}
	}

It failed on:
ConstructItems(GetData(), OtherData, OtherNum);

It seems that OtherData has a garbage value.

Ok, so I fixed this, at least for my use case. Basically, the conversion code to 4.23 is broken in UEPyModule.cpp. In particular, the problems are in lines 3118 and 3133.

I replaced 3118 with:

		// NOTE: only takes the first result from u_property->ArrayDim (can be refactored to do a loop)
		FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(casted_prop->ContainerPtrToValuePtr<void>(u_obj->ue_object));

Then, I replaced 3133 with:
casted_prop->SetMulticastDelegate(casted_prop->ContainerPtrToValuePtr<void>(u_obj->ue_object), multiscript_delegate);

Make these changes, rebuild, and it should work.

I'm seeing this crash too. So far this change is working for me (I've changed it only in ue_bind_pyevent and only tested a tiny bit):

if (auto casted_prop = Cast<UMulticastDelegateProperty>(u_property))
{
    FScriptDelegate script_delegate;
    UPythonDelegate* py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(u_obj->ue_object, py_callable, casted_prop->SignatureFunction);
    // fake UFUNCTION for bypassing checks
    script_delegate.BindUFunction(py_delegate, FName("PyFakeCallable"));

#if ENGINE_MINOR_VERSION < 23
    FMulticastScriptDelegate multiscript_delegate = casted_prop->GetPropertyValue_InContainer(u_obj->ue_object);
    multiscript_delegate.Add(script_delegate);
#else
    casted_prop->AddDelegate(script_delegate, u_obj->ue_object);
#endif
}
commented

Ok, so I fixed this, at least for my use case. Basically, the conversion code to 4.23 is broken in UEPyModule.cpp. In particular, the problems are in lines 3118 and 3133.

I replaced 3118 with:

		// NOTE: only takes the first result from u_property->ArrayDim (can be refactored to do a loop)
		FMulticastScriptDelegate multiscript_delegate = *casted_prop->GetMulticastDelegate(casted_prop->ContainerPtrToValuePtr<void>(u_obj->ue_object));

Then, I replaced 3133 with:
casted_prop->SetMulticastDelegate(casted_prop->ContainerPtrToValuePtr<void>(u_obj->ue_object), multiscript_delegate);

Make these changes, rebuild, and it should work.

Solved my issue! Thanks!