Unresolved external on slate class from other module

Hi, I’m trying to create a Slate class in a Utils module that I can use in other modules in my plugin. I get an unresolved external error when trying to create it though. I’ve gone through the usual:

  • Made sure the module is added to the plugin
  • Made sure that the module is added to the dependencies of other modules
  • Made sure the headers are included
  • Made sure that all functions have been implemented
  • Added the API macro to the class
  • Rebuilt the project files

This is the error:

0>Module.RPGFrameworkDialogEditor.cpp.obj: Error LNK2019 : unresolved external symbol "public: class TSharedRef<class SRPGFrameworkEditorCommonList,0> __cdecl FRPGFrameworkEditorUtilsModule::CreateCommonRowList(void)" (?CreateCommonRowList@FRPGFrameworkEditorUtilsModule@@QEAA?AV?$TSharedRef@VSRPGFrameworkEditorCommonList@@$0A@@@XZ) referenced in function "protected: void __cdecl FRPGFrameworkDialogEditor::CreateAndRegisterRowListTab(class TSharedRef<class FTabManager,0>)" (?CreateAndRegisterRowListTab@FRPGFrameworkDialogEditor@@IEAAXV?$TSharedRef@VFTabManager@@$0A@@@@Z)
0>UE4Editor-RPGFrameworkDialogEditor.dll: Error LNK1120 : 1 unresolved externals
0>Microsoft.MakeFile.Targets(44,5): Error MSB3073 : The command ""C:\Program Files\Epic Games\UE_4.27\Engine\Build\BatchFiles\Build.bat" ProjectDeGeerEditor Win64 Development -Project="C:\Users\Sarlack\Documents\Unreal Projects\ProjectDeGeer\ProjectDeGeer.uproject" -WaitMutex -FromMsBuild" exited with code 6.

Here’s the class (I’ve removed unnecessary details, like all the custom class methods and members to save space):

class RPGFRAMEWORKEDITORUTILS_API SRPGFrameworkEditorCommonList : public SCompoundWidget
{
SLATE_BEGIN_ARGS(SRPGFrameworkEditorCommonList){}
		
	SLATE_END_ARGS()
	
public:
	void Construct(const FArguments& InArgs);

];

The uplugin file:

"Modules": [
    {
       "Name": "RPGFrameworkCore",
       "Type": "Runtime",
       "LoadingPhase": "Default"
    },
    {
       "Name": "RPGFrameworkDialogEditor",
       "Type": "Editor",
       "LoadingPhase": "Default"
    },
    {
       "Name": "RPGFrameworkItemEditor",
       "Type": "Editor",
       "LoadingPhase": "Default"
    },
    {
       "Name": "RPGFrameworkEditorUtils", <---- this is the module
       "Type": "Editor",
       "LoadingPhase": "Default"
    }
],

The dependencies of the module I want to use Utils in:

PrivateDependencyModuleNames.AddRange(
    new string[]
    {
       "CoreUObject",
       "InputCore",
       "Engine",
       "Slate",
       "SlateCore",
       "AssetTools",
       "UnrealEd",
       "PropertyEditor",
       "Projects",
       "ToolMenus",
       "GraphEditor",
       "EditorStyle",
       "BlueprintGraph",
       "RPGFrameworkCore",
       "RPGFrameworkEditorUtils", <---- This is the one
       // ... add private dependencies that you statically link with here ... 
    }
    );

Header files on the class I want to add the Slate object to:

#include "RPGFrameworkDialogEditor.h"

#include "Slate.h"
#include "RPGFrameworkDialogGlobalNames.h"
#include "DialogDetails/DetailsConditionAndEventWidget.h"
#include "DialogGraph/RPGFrameworkDialogGraphNode.h"
#include "DialogGraph/RPGFrameworkDialogGraphSchema.h"
#include "Framework/Commands/GenericCommands.h"
#include "Kismet2/BlueprintEditorUtils.h"

#include "RPGFrameworkEditorUtilsModule.h" <---- Here
#include "RPGFrameworkEditorUtilsCommonList/RPGFrameworkEditorCommonList.h" <--- And here

#include "Styling/SlateStyleRegistry.h"
#include "Widgets/Colors/SColorBlock.h"
#include "Widgets/Layout/SWidgetSwitcher.h"

This is where I create the object (Inside a function in one of my modules that is not the Utils):

FRPGFrameworkEditorUtilsModule& FrameworkEditorUtils = FModuleManager::Get().GetModuleChecked<FRPGFrameworkEditorUtilsModule>("RPGFrameworkEditorUtils");

RowListTabWidget = FrameworkEditorUtils.CreateCommonRowList(); <---
RowListTabWidget->OnAddListRow.BindRaw(this, &FRPGFrameworkDialogEditor::Callback_OnAddDialogButtonClicked);

The function being called (CreateCommonRowList) is this one (Inside the utils):

// Declaration
TSharedRef<class SRPGFrameworkEditorCommonList> CreateCommonRowList();
// In the Utils CPP
TSharedRef<SRPGFrameworkEditorCommonList> FRPGFrameworkEditorUtilsModule::CreateCommonRowList()
{
    TSharedRef<SRPGFrameworkEditorCommonList> CommonList = SNew(SRPGFrameworkEditorCommonList);
    return CommonList;
}

Any ideas? Thanks

It seemed to work when I created the Slate object directly like this:

RowListTabWidget = SNew(SRPGFrameworkEditorCommonList);

I’m still curious why the helper function didn’t work?