C++ Interface Cast returns NULL when implemented with Editor

Hello. I made an Interface that should be able to be implemented in both code and Blueprints.

This is the Interface:

InterfaceCoversArea.h

UINTERFACE()
class UInterfaceCoversArea : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class IInterfaceCoversArea
{
	GENERATED_IINTERFACE_BODY()

public:

	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "Get Area Coverage Radius"), Category = "Interface Covers Area")
	float GetAreaCoverageRadius();
};

My code class implementing it:

ParentCharacter.h

UCLASS()
class AParentCharacter : public ACharacter, public IInterfaceCoversArea
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ParentCharacter")
	float AreaCoverage = 40.f;
...

	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "Get Area Coverage Radius"), Category = "Interface Covers Area")
	float GetAreaCoverageRadius();
};

ParentCharacter.m

float AParentCharacter::GetAreaCoverageRadius_Implementation()
{
	return AreaCoverage;
}

This is how I’m using it in another class:

float CurrentRange = OwnerActor->GetHorizontalDistanceTo(TargetActor);
IInterfaceCoversArea* InterfaceCoversAreaActor = Cast<IInterfaceCoversArea>(OwnerActor);
if (InterfaceCoversAreaActor != nullptr)
{
     CurrentRange -= InterfaceCoversAreaActor->Execute_GetAreaCoverageRadius(Cast<UObject>(InterfaceCoversAreaActor));
}

This works with Blueprints that inherti from ParentCharacter, but when I implement the interface using the Editor

62062-interfacecoversarea.jpg

I get NULL from

Cast<IInterfaceCoversArea>(OwnerActor);

What could be the problem?

1 Like

Omg, figured it out. I found the solution >>here<<.

I needed to use the following syntax, it works on both cases: when implementing the interface in code and purely on blueprints

if (TargetActor->GetClass()->ImplementsInterface(UInterfaceCoversArea::StaticClass()))
{
	CurrentRange -= IInterfaceCoversArea::Execute_GetAreaCoverageRadius(TargetActor);
}
3 Likes

Hey Ghar :slight_smile:

I wrote a tutorial about Interfaces which can be implemented by Blueprints and C++ Classes.
Maybe you will find a more elegant solution in my attempt :slight_smile:

How To Make C++ Interfaces Implementable By Blueprints(Tutorial)

Good luck

1 Like

Same issue.

The cast to the interface looks like there is an engine bug. Sad to have to use ghar’s workaround - especially given that Rama’s tutorial with the Cast is one of the first google hits.

UObjectBaseUtility::GetInterfaceAddress is what is doing the casting. The c++ interface has the CLASS_Native flag (because it was written in C++), so it goes to the native lookup. This part looks like a copy paste of ::GetNativeInterfaceAddress - which fails if bImplementedByK2 is true (which it is in this situation).

removing that flag check allows it to properly return the interface structure (with 0 offset, so the calculation is fine), but of course this is an engine change.

Hopefully staff will weigh in?

This won’t work. If it’s implemented in BP, then at the C++ level the object does not inherit from the C++ interface and so it doesn’t have the virtual function table entries for the methods. Allowing the cast to return the address is just a recipe for crashing the engine.

This is simply not a bug, it’s a limitation of the way BP is built on top of C++. The accepted answer is not a workaround, it’s the (admittedly ugly) intended approach.

I wrote very clear way to do this.

Snippet from here: Interface implementation check for Unreal Engine 4 (UE4) ($1832992) · Snippets · District Zero / Unreal Engine 4 Snippets · GitLab

Code:

#pragma once


#include "Interface.h"

/**
* Fast and full checking of interface implementation including nullptr check, C++ cast check and blueprint check
* @param TIInterfaceType is interface IClass (not UClass)
* @param object          is pointer to check
* @return                true if object implements TIInterfaceType, false if nullptr or doesn't implement
*/
template<typename TIInterfaceType>
FORCEINLINE bool IsInterfaceImplementedBy(const UObject* const object)
{
    return 
        // Nullptr is invalid
        object && 
        // C++-style cast much faster
        (Cast<TIInterfaceType>(object) || 
        // But blueprint implementation pass only this check
        object->GetClass()->ImplementsInterface(TIInterfaceType::UClassType::StaticClass()));
}

You need to include this header into every interface declaration and use it in C++:

void ATestCodeGameModeBase::CallDoSomething(UObject* object) 
{
    // Clear check of what we mean
    if (IsInterfaceImplementedBy<ITestInterface>(object))
    {
        ITestInterface::Execute_DoSomething(object);
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Object does not implement interface"));
    }
}

// vs


void ATestCodeGameModeBase::CallDoSomething(UObject* object)
{
    // Doesn't understandable
    if (object && object->GetClass()->ImplementsInterface(UTestInterface::StaticClass()))
    {
        ITestInterface::Execute_DoSomething(object);
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Object does not implement interface"));
    }
}

I wrote clear approach to check interface types. See my answer.

So, does this mean there is no way at all to call a native interface function on a blueprint-implemented interface (but only what’s exposed to BP)?

Is this still working?
For me this Execute function always returns NULL result.

1 Like

Hi! I had the same problem, I created an interface on C++ and added in the editor to a Widget Blueprint, but the cast return a null.

IResultsInterface* sr =  Cast<IResultsInterface>(object);
if (sr)  sr->SetSumaryData(data);  //fail

The solution was to use the static version of the function:

if (object->GetClass()->ImplementsInterface(IResultsInterface::StaticClass()))
{
	IResultsInterface::Execute_SetSumaryData(b, data);
}

Engine was 5.2.

1 Like