Download

Casting UStruct to derrived struct

I’m trying to implement a method where I pass along a base struct, which might be of type ‘derrived struct’.

However, when casting, I’m getting the following exception:



'To *TCastImpl<From,To,ECastType::UObjectToUObject>::DoCast(UObject *)': cannot convert argument 1 from 'From *' to 'UObject *'


To give you some basic information, here are my struct definitions:

Please be aware, these are just test structs, so the derrived struct doesn’t even have extra parameters, the message struct doesn’t even have message text.

FMessageStructBase:



#pragma once

#include "CoreMinimal.h"
#include "MessageStruct.generated.h"

USTRUCT()
struct FMessageStructBase
{
    GENERATED_BODY()

public:
    UPROPERTY()
    int Id;
};


FMessageStructDerrived:



#pragma once

#include "CoreMinimal.h"
#include "MessageStruct.h"
#include "MessageStructDerrived.generated.h"

USTRUCT()
struct FMessageStructDerrived : public FMessageStructBase
{
    GENERATED_BODY()

public:
};


The following code all contains the required include files for the structs in the cpp file:



#include "MessageStruct.h"
#include "MessageStructDerrived.h"


The code I use to test the casting is the following:



FMessageStructDerrived messageStruct;
FMessageStructBase* messageStructBase = &messageStruct;
FMessageStructDerrived* derrived = Cast<FMessageStructDerrived>(messageStructBase);


A “fix” I found, is to use static_cast instead, which compiles, and the cast succeeds. However, in the case of the message not being of the type FMessageStructDerrived, it will crash, since it’s not a safe cast:



FMessageStructDerrived* derrived = static_cast<FMessageStructDerrived*>(messageStructBase);


Luckily, I can of course use a dynamic_cast! … Oh. Wait. No I can’t, because if I use the following:



FMessageStructDerrived* derrived = dynamic_cast<FMessageStructDerrived*>(messageStructBase);


It will give me the following error:



'dynamic_cast': 'FMessageStructBase' is not a polymorphic type


I hope someone can help me figure out how I can properly cast these UStructs.

Thanks in advance!

You can’t use “normal” casts for UObjects. You need to use the Cast methods you were originally using.

You can either check for null after you do the Cast (to prevent accessing a failed cast), or do a IsChildOf check before the cast (which may be a bit redundant).




if (FMessageStructDerived* derivedStruct = Cast<FMessageStructDerived>(&myStruct))
{
   // Cast was successful, continue on.
}

// Same logic as above, but using IsChildOf
if (myStruct.IsChildOf<FMessageStructDerived>())
{
    FMessageStructDerived* derivedStruct = CastChecked<FMessageStructDerived>(&myStruct); // CastChecked will crash on a failed cast, but our IsChildOf guarantees that our cast will be safe.
}



^ the above will not work, since these are ustructs, not uobjects

There is no dynamic cast for ustructs in unreal. Basically, you’re not supposed to use them this way.

If the goal is to expose this to blueprint, you also won’t be able to pass a FMessageStructDerived to a blueprint method expecting a FMessageStructBase. If it isn’t, I guess you could do some “manual” runtime type checking by adding a EMessageStructType to each and checking that, but it’s pretty ugly. You could also use uobjects instead, but that has a pretty huge overhead for low level things.

The best way would be to design the system in a way that it does not need dynamic casts with simple structs at all.

[TABLE=“cellspacing: 0”]

UObject [TABLE=“cellspacing: 0”]
[TR]
[TD]

https://forums.unrealengine.com/core/image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

					[UField](https://api.unrealengine.com/INT/API/Runtime/CoreUObject/UObject/UField/index.html) 						[TABLE="cellspacing: 0"]

[TR]
[TD]

https://forums.unrealengine.com/core/image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

								[UStruct](https://api.unrealengine.com/INT/API/Runtime/CoreUObject/UObject/UStruct/index.html) 									[TABLE="cellspacing: 0"]

[TR]
[TD]

https://forums.unrealengine.com/core/image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

											UScriptStruct

[/TD]
[/TR]

[/TD]
[/TR]

[/TD]
[/TR]

Yes I guess they are UObjects.
But you won’t be able to use them the same way you expect to use GeneratedClasses.