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