How to call a C++ Interface function from another C++ Script

I have a HealthInterface, which has a method GetHealthPercentage(float& OutPercentage), which is defined in C++.
I need to call that function from any actor who implements that interface.

I tried casting it as most people online suggest:

if(ActorToRegister->Implements<UHealthInterface>())
		{
			float newHealth=0.5f;
			IHealthInterface* healthInterface = Cast<IHealthInterface>(ActorToRegister);
			healthInterface->GetHealthPercentage(newHealth);
			
			OnUpdateHealthbar.Broadcast(ActorToRegister, newHealth, 0);
		}	

That throws this error:

unresolved external symbol "private: static class UClass * __cdecl UHealthInterface::GetPrivateStaticClass(void)" (?GetPrivateStaticClass@UHealthInterface@@CAPEAVUClass@@XZ) referenced in function "public: void __cdecl AViewHUD::RegisterHealthbar(class AActor *)" (?RegisterHealthbar@AViewHUD@@QEAAXPEAVAActor@@@Z)

I also tried making the function a “BlueprintNativeEvent”, so I could use the “Execute_FunctionName” but found out that if it is an interface, it does not allow you to create a C++ native Implementation, throwing an error “Function already has a body

I have also tried a work- around where I call that function from a different function created in a function library. But I still need a reference to the interface using
TScriptInterface<IHealthInterface>, which is essentialy what casting to Interface returns in blueprints.

I have no idea how to initialize/get this in C++. I tried if it would auto-convert if I just put in the Actor there:

float newHealth=0.5f;
UHealthInterfaceUtils::GetHealthPercentage(ActorToRegister,newHealth);

Throwing errors:

unresolved external symbol "private: static class UClass * __cdecl UHealthInterface::GetPrivateStaticClass(void)" (?GetPrivateStaticClass@UHealthInterface@@CAPEAVUClass@@XZ) referenced in function "public: void __cdecl AViewHUD::RegisterHealthbar(class AActor *)" (?RegisterHealthbar@AViewHUD@@QEAAXPEAVAActor@@@Z)

and

unresolved external symbol "public: static void __cdecl UHealthInterfaceUtils::GetHealthPercentage(class TScriptInterface<class IHealthInterface>,float &)" (?GetHealthPercentage@UHealthInterfaceUtils@@SAXV?$TScriptInterface@VIHealthInterface@@@@AEAM@Z) referenced in function "public: void __cdecl AViewHUD::RegisterHealthbar(class AActor *)" (?RegisterHealthbar@AViewHUD@@QEAAXPEAVAActor@@@Z)

I tried creating an instance and assigning the Object

float newHealth=0.5f;
TScriptInterface<IHealthInterface> interfaceScript;
interfaceScript.SetObject(ActorToRegister);
UHealthInterfaceUtils::GetHealthPercentage(interfaceScript, newHealth);

This throws 2 errors:

unresolved external symbol "private: static class UClass * __cdecl UHealthInterface::GetPrivateStaticClass(void)" (?GetPrivateStaticClass@UHealthInterface@@CAPEAVUClass@@XZ) referenced in function "public: void __cdecl AViewHUD::RegisterHealthbar(class AActor *)" (?RegisterHealthbar@AViewHUD@@QEAAXPEAVAActor@@@Z)

and

unresolved external symbol "public: static void __cdecl UHealthInterfaceUtils::GetHealthPercentage(class TScriptInterface<class IHealthInterface>,float &)" (?GetHealthPercentage@UHealthInterfaceUtils@@SAXV?$TScriptInterface@VIHealthInterface@@@@AEAM@Z) referenced in function "public: void __cdecl AViewHUD::RegisterHealthbar(class AActor *)" (?RegisterHealthbar@AViewHUD@@QEAAXPEAVAActor@@@Z)

At this point… I am at a loss as to what to do.
Is there really no way to call a C++ interface function in C++?!

I would also like to say I am very new to interfaces in general and also in UE5

Don’t use casts on interfaces. Use Implements<> and Execute_.

if (ActorToRegister->Implements<UHealthInterface>())
{
    float hp = IHealthInterface::Execute_GetHealthPercentage(ActorToRegister);
}

BlueprintNativeEvent works fine, you just need to implement the _Implementation suffix version of the function and not touch the original one.

class IHealthInterface
{
	GENERATED_BODY()
public:
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
    float GetHealthPercentage();
    //optional default implementation
    //virtual float GetHealthPercentage_Implementation() { return 0.f; }
}

class AMyCharacter : public ACharacter, public IHealthInterface
{
GENERATED_BODY()

    //~ Begin HealthInterface
    virtual float GetHealthPercentage_Implementation() override;
    //~ End HealthInterface
}

Are you declaring the health interface in a different module, eg. in its own separate engine/project plugin ?
If that is the case, you must add module API specifier to the interface class :

class HEALTHMODULE_API IHealthInterface

And you must import that module as a dependency wherever you are using it, eg. Project.Build.cs :

PublicDependencyModuleNames.AddRange(new string[] {
    //...
    "HealthModule"
});