Got confused with casting

For UE4, I always use Cast<> and get away with it. But I need to edit Editor source now, and here I stumbled on needing to do this:


SFbxSceneOptionWindow sceneOptionWindow = InSlateWindow.Get().GetContent().Get();

SFbxSceneOptionWindow is upclass of SWidget

InSlateWindow.Get().GetContent() return const SWidget, but also InSlateWindow.Get().GetContent().Get() encapsulates it in TSharedRef

This is maddness!! How can I fugure out, should I use explicit cast here, or static cast, or dynamic cast? Is there some golden rule I could stick to and follow, when it comes to TSharedRef pointers, to never get confused with this sort of casts? I know there is documentation, but wrapping my head around it is difficult. I will do this eventually, but any help here is appreciated.

First, it seems like you are trying to cast a const object, to a non-cost object - which would require a const_cast.

Second, I would just use a C style cast. I’m not a huge C style cast fan, but since its Editor code and that code doesn’t need to be ridiculously performant - a C style cast is fine.

Try this and see what you get:



const SFbxSceneOptionWindow* sceneOptionWindow = (const SFbxSceneOptionWindow*)InSlateWindow.Get().GetContent().Get();


I think you want dynamic_cast.

if Get() returns a SFbxSceneOptionWindow*const


SFbxSceneOptionWindow* sceneOptionWindow = dynamic_cast<SFbxSceneOptionWindow*>(InSlateWindow.Get().GetContext().Get());

if Get() returns a const SFbxSceneOptionWindow*


const SFbxSceneOptionWindow* sceneOptionWindow = dynamic_cast<const SFbxSceneOptionWindow*>(InSlateWindow.Get().GetContext().Get());

either way, if the pointer is to an object that is not a SFbxSceneOptionWindow the dynamic_cast<…>(…) would return nullptr. It’s been awhile since i’ve used dynamic_cast but I recall it working this way.

Regular C casts when you don’t know for sure the type will always succeed, in that you will end up with a pointer even if the thing pointed to is not the type of the pointer. So you want to only use C casts either when you are 100% positive that what you are casting to is compatible. Specific with inheritance and interfaces you should be extra cautious of invoking VTable/virtual members from a pointer acquired using a C cast. Its not always incorrect to do so, but basically if your unsure or unwilling to confirm that the type you are dealing with is that of the C cast, use dynamic_cast (Keeping in mind there is some overhead in doing so, you don’t want to redundantly use it).

Thank you guys! I will work this out from here.

I’ve got a conversion code, which yields no errors itself:


	FSlateApplication& application = FSlateApplication::Get();

	if (application.GetActiveModalWindow().IsValid())
	{
		TSharedPtr<SWindow> window = application.GetActiveModalWindow();
		SWindow* windowPtr = window.Get();

		if (windowPtr != nullptr)
		{

                            TSharedRef<const SWidget> content = windowPtr->GetContent();
			    const SWidget& fbxScene = content.Get();
			    SWidget& fbxSceneNC = const_cast<SWidget&>(fbxScene);
			    SFbxSceneOptionWindow& sceneOptionWindow = (SFbxSceneOptionWindow&)(fbxSceneNC);

				FString MaterialBasePath = "/Game/Worldmap/Materials/";
				FText inText = FText::FromString(MaterialBasePath);

				sceneOptionWindow.OnMaterialBasePathCommited(inText, ETextCommit::Type::Default);
				sceneOptionWindow.OnImport();
                }
           }

But, if those 2 lines are included:


				sceneOptionWindow.OnMaterialBasePathCommited(inText, ETextCommit::Type::Default);
				sceneOptionWindow.OnImport();

I oddly get linker error:

Where does this linker error comes from?

Looks like you’re missing reference for the FBXSceneImporter in your project. You’ll need to add it to your .Build.cs file as a dependency.

Ah, I see! Thank you. I’ll try putting some names in there randomly and see if it works. I already included ‘UnrealEd’, wonder why that file is out of build, as it looks like it is inside ‘UnrealEd’ to me. I must be wrong somewhere

Maybe I can not include this file directly like this, need somehow differently?

Now that I think, maybe that fbx importer file is depended on some other modules. Need to find a way to track that down. hmmm

Found it. Not all classes are exported. Guess I’ll need to rebuild UE4 from source.

Solved! Needs to add export_API prefixes.