InerfaceCast returns null for blueprint classes implementing that interface

Branch 4.1 tag 4.1.1
I don’t know if it is an intended feature or a bug, but you cannot use InterfaceCast to expose class interfaces that are set in blueprint.
The code below is demonstrated a solution:

//Interface
#pragma once
#include "KinectFunctionLibrary.h"
#include "KinectListenerInterface.generated.h"



UINTERFACE(Blueprintable)
class UKinectListenerInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class IKinectListenerInterface
{
	GENERATED_IINTERFACE_BODY()

public:

	UFUNCTION(BlueprintImplementableEvent, Category = NUI)
		void ReciveBody(const FBodyFrame& BodyFrame);
};

//Event Dispatcher

void  KinectEventDispatcher::DispatchEvent(){


	FBodyFrame Frame = KinectSensor::Get().GetBodyFrame();




	for (TObjectIterator<AActor> It; It; ++It) //Iterate over all actors
	{
		IKinectListenerInterface* ListenerInterface = NULL;

		//Try InterFaceCasting
		IKinectListenerInterface = InterfaceCast<IKinectListenerInterface>(*It);

		//Problem/Bug/Feature? ListenerInterface is null, Event is not triggered
		if (ListenerInterface)
			ListenerInterface->Execute_ReciveBody(Frame);
    
            //Solution: Triggers the event 
		if ((*It)->GetClass()->ImplementsInterface(UKinectListenerInterface::StaticClass())){

			IKinectListenerInterface::Execute_ReciveBody((*It), Frame);

		}

	}


}

Sorry if I was unclear, in my code lines 36 to 43 are commented out and they are the reason I reported this bug.
Lines 46 to 50 are the solution to the problem I had in lines 36 to 43.
This snippet is the event dispatcher part of my Kinect plugin.
The goal of this code is to make my plugin native code “free” so everyone could use it without the need to see native code.
To achieve that I created an Interface IKinectListenerInterface which can be implemented inside the editor by any class that the user wants to receive events from the Kinect.
While exposing native interfaces to blueprints is pretty much straight forward the other way using InterfaceCast method described here:

on an Blueprint generated class returns null.
I hope that explains my report better.

Hi lion032. I am little unsure about exactly what you are trying to do in a couple lines of your code sample. In line 36, it looks like you are creating a pointer named ListenerInterface, and setting the value to NULL. Then, in line 42, you are checking the see if ListenerInterface contains a valid value, which it does not since it is still NULL, so the following line never triggers.

Is your InterfaceCast in line 39 supposed to be updating the value stored in ListenerInterface? If you can clarify what those lines are trying to do, I can look into this a bit more for you.

Thank you for the clarification. I will continue looking into this for you. I am still a little unsure where ListenerInterface is being set to a value other than NULL, but I think I have what I need to investigate this.

I set it to null to avoid access violation in case that it initialized to garbage value

I saw where you had declared the pointer and set it to NULL. I was just unsure where the pointer’s value was being changed to something else so the if check would work. I have reached out to one of our developers for some insight into this issue. I hope to receive some feedback from him within a few days.

Thanks!
I found a workaround (lines 46 to 50) so personally this bug doesn’t bother me anymore, hope my workaround could assist you.

that’s a nifty solution, thanks for sharing Lion!

Rama

No! Thank you Rama!
I’m reading one of your tutorials as we speak :smiley:
(And I kinda need your help with something about it :P)

hee hee!

well you did great research yourself, so congrats!

you can pm me about your issue (so this thread stays focused)

If you’re using a BP interface, you need to use ScriptInterfaceCast instead of an InterfaceCast. You can check out the difference in Casts.h, where the two functions are defined.

The root of the problem with using the InterfaceCast is that it’s looking for a native entry point for the interface. But, since it’s implemented in BP, there is no native entry point, and you need to use the ScriptInterfaceCast to properly set things up.

However, the best way to use interfaces is with the IMyInterface::Execute_MyFunction, because that handles both the native and BP cases via the same path.

Hope that helps!

Thanks!
But if you’ll look at lines 46-50 in the code in the original post I have already proposed a solution in the bug report using IMyInterface::Execute_MyFunction, I reported the bug after finding that workaround :slight_smile:

Yup, saw those, but figured people might be interested in the “why” as well. Glad you’re up and rolling!

+1 for the “Why” explanation. I was looking at the Strategy example and wondering if there was a reason to prefer the IMyInterface::Execute_MyFunction approach over an InterfaceCast and now I know there is and why. The why is pretty important for really understanding something.

I just wanted to say I found this question really helpful in getting my interface stuff to work.

I wrote up a more detailed summary of what is going on and why at Grand unified C++/blueprint cast interface explanation - UI - Unreal Engine Forums
in case others have similar issues or in case you were wondering why this is so complicated. :slight_smile:

This is literally the only place on the internet where I’ve found this ScriptInterfaceCast function mentioned. It certainly isn’t in my Casts.h file.

Was it removed from the codebase?

Hi ClaudioFreda,

Casts were overhauled in version 4.6 to simplify their use. Part of that change was the removal of ScriptInterfaceCast(). From the version 4.6 release notes:

Simplified Casting

  • Easily cast between Unreal classes using the improved Cast() function. You can even cast between interfaces and classes. We also now support using dynamic_cast to cast between Unreal types, if you prefer that.

If you are having some trouble with casting, please submit a new question since casting has changed significantly from when this question was originally asked.

Tim

Just for completion.
What Tim Lincoln was looking for is line 39.

//Wrong
IKinectListenerInterface = InterfaceCast<IKinectListenerInterface>(*It);

//Right
ListenerInterface  = InterfaceCast<IKinectListenerInterface>(*It);

Without that change the If check in Line 42 will not work because ListenerInterface is never changed and will be NULL.