Returning an interface from C++?

In my current project, I’m converting some blueprints into C++.
One of these blueprints is able to search through all actors within the current scene, and return the interface for the first valid object which utilizes said interface:

https://forums.unrealengine.com/attachment.php?attachmentid=57682&d=1442544455

As you can see, returning an interface works just fine in blueprints. In C++, however, I’ve tried several different ways to return an interface, and can’t get any of them to compile.
Here’s some of the following setups (and their corresponding errors) that I’ve tried:


  • IMarionettistInterface *FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error);

    ScriptInterface.h(144): error C2664: ‘void FScriptInterface::SetObject(UObject *)’ : cannot convert argument 1 from ‘IMarionettistInterface *’ to ‘UObject *’
    MarionettistUtilities.h(8) : see reference to function template instantiation ‘InterfaceType &TScriptInterface::operator =(UObjectType *)’ being compiled with…

  • UMarionettistInterface *FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error);

    ScriptInterface.h(146): error C2440: ‘initializing’ : cannot convert from ‘UMarionettistInterface *’ to ‘IMarionettistInterface *’
    MarionettistUtilities.h(8) : see reference to function template instantiation ‘InterfaceType &TScriptInterface::operator =(UObjectType *)’ being compiled with…

  • void FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error, IMarionettistInterface *Interface);

    MarionettistUtilities.h(8): error C2664: ‘void UMarionettistUtilities::FindMarionettistInScene(TEnumAsByte,bool &,IMarionettistInterface *)’ : cannot convert argument 3 from ‘TScriptInterface’ to 'IMarionettistInterface *

  • void FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error, UMarionettistInterface *Interface);

    MarionettistUtilities.h(8): error C2664: ‘void UMarionettistUtilities::FindMarionettistInScene(TEnumAsByte,bool &,UMarionettistInterface *)’ : cannot convert argument 3 from ‘TScriptInterface’ to ‘UMarionettistInterface *’

  • void FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error, const IMarionettistInterface &Interface);

    MarionettistUtilities.h(12) : Missing ‘*’ in Expected a pointer type


… Anyhow, I’m sure you get the idea. I’m a bit stumped how this is actually done.

Oh, and in case you’re interested, line #8 of MarionettistUtilities.h is GENERATED_UCLASS_BODY(), and line #12 is the above function I’m trying to compile (currently, it’s the only one in the class).

So what is the correct way to convert this blueprint into C++?

Hi MichaelWion,

Unfortunately I can’t se your image but You can do two things to workaround this:

  1. You can add method GetObject to You interface and simply return UObject* from it for every class that will implement this interface:

    virtual UObject* IMarionettistInterface::GetObject() { return nullptr; }

    class Marionettist : public AActor, public IMarionettistInterface
    {
    virtual UObject* GetObject() override {return this;}
    }

This way You will get UObject* so compiler won’t complain.

  1. You can return UObject* in the method instead of IMarionettistInterface* so there is no problem with conversion.

    UObject* FindMarionettistInScene(TEnumAsByte MarionettistName, bool &Error);

You should remember that IInterface is just a pure C++ class so it’s not convertible to UObject* in any way.

Here is a link to the documentation where You can check what are benefits of using UInterfaces.

Interfaces

I found that the following definition compiles:

static void FindMarionettistInScene(TEnumAsByte<EMarionettist> MarionettistName, bool &Error, TScriptInterface<IMarionettistInterface> &Interface);
1 Like

Thanks, see my answer to see how I solved it without a workaround

This solution works in blueprint only setup but not for interface made in C++ and inherited in blueprint.

Unreal provides a TScriptInterface<> type which is designed to wrap an object as a specific interface. It’s the official suggested way to hold on to both the object reference safely and the interface it’s supposed to be presenting. You can use it like this:

TScriptInterface<IDoSomeThings> SomethingInstance;

When you want to use this stored reference, you call it using the overloaded -> operator, i.e.:

int Num = SomethingInstance->GetNumberOfThings();

Simple in theory, but there’s one major problem with this, and that’s that TScriptInterface<> derives the interface pointer using Cast<>. And as we established earlier, Cast<> will always return nullptr if the instance in question is only implementing the interface at the Blueprint level, and none of its superclasses implement it in C++.

The thing is, you can still make TScriptInterface<> work in this scenario, by instead calling:

int Num = IDoSomeThings::Execute_GetNumberOfThings(SomethingInstance.GetObject());

Quoted from here: UE4 C++ Interfaces - Hints n Tips · SteveStreeting.com