UWidgetComponent::GetUserWidgetObject() LNK error.

Hey all,

I’m getting a link error when trying to access the UserWidget object tied to my WidgetComponent.

**Error 14 error LNK2019: unresolved external symbol "public: class UUserWidget * __cdecl UWidgetComponent::GetUserWidgetObject(void)const " (?GetUserWidgetObject@UWidgetComponent@@QEBAPEAVUUserWidget@@XZ) referenced in function "public: virtual void __cdecl UWD_CameraTrace::TickComponent(float,enum ELevelTick,struct FActorComponentTickFunction )" (?TickComponent@UWD_CameraTrace@@UEAAXMW4ELevelTick@@PEAUFActorComponentTickFunction@@@Z) C:\Users\Austin\Documents\Unreal Projects\WD_Torture\Intermediate\ProjectFiles\WD_CameraTrace.cpp.obj WD_Torture

UUserWidget *MyWidget = MyComponent->GetUserWidgetObject();

if (MyWidget)
{
    // Do Stuff Here
}

I’m not too sure as to why I’m getting the error. I’ve been searching for a couple of hours now, and I’ve come up with nothing. Hopefully someone can help!?!?

Thanks a bunch, all.

  • Austin

Hi Austin,

The functions in WidgetComponent aren’t exported in a way that other modules can communicate with them.

If you were to look at WidgetComponent.h, somewhere in the UCLASS metadata it will read MinimalAPI, which doesn’t export the symbols, hence “unresolved external symbol” when you’re trying to call GetUserWidgetObject();

By removing that MinimalAPI metadata and adding the module API prefix to the class declaration line in the header:

class UMG_API UWidgetComponent : public UPrimitiveComponent

You can export every function so that they can be accessed by other modules (such as your gameplay module).

This does involve making a change to the UE4 source code though, unless they decide to export the symbols by default in future.

In order to pull those headers in from your external module (UMG), open your Project.Build.cs file in your game module folder, and on the PublicDependancyModuleNames line, add the UMG module, which is from the UMG folder name. Here’s mine:

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "Slate", "SlateCore", "HeadMountedDisplay" });

Then in the class you’re working in #include “WidgetComponent.h” and “UserWidget.h”, or an extended version of that class.

Also found this: “Functions and classes that need to be accessed outside of their module must be exposed via the *_API macros. Each item that is exposed comes with a compile-time cost, so be sure to only expose what is needed. If you only need access to a single function in a class, exposing just that function instead of the class can save a significant amount of time when compiling.”

https://docs.unrealengine.com/latest/INT/Programming/Basics/index.html

Also be aware that somewhere along the way, this process has borked my hot reload, and the unresolved external symbol error will keep happening unless you recompile with the editor closed and make sure it’s been closed for long enough that the editor is no longer in memory and hot reload doesn’t still fire.

I’ve gotten as far as getting my own traces to hit the widgetcomponent, pick up the widgets (such as a text box) using some maths, but I’m lacking the final part of the puzzle, which is setting the focus to the WidgetComponent and the textbox inside it so I can type on it. The default behaviour of widgetcomponent isn’t quite what I’m looking for, but this is a story for another answers post I think. Hope this helps!

Running into this same issue. I see other people have successfully used GetUserWidgetObject() with out any issues, so I feel like it is possible without changing core code. I also tried to change UWidgetComponent.h to use the UMG_API and it gave an error: “error C2487: ‘GetPrivateStaticClass’ : member of dll interface class may not be declared with dll interface” .

Hmm I think i may need to build the Engine files again. But git is taking forever :slight_smile:

okay so, After compiling the engine source code exposing the WidgetComponent to the API , I was able to compile my code. Thanks for your detailed answer it helped me learn a lot about the build process and now I have all the .cpp files too which will make life easier :slight_smile:

I had fixed the issue earlier by just implementing that function definition in another .cpp file, which allowed the project to compile and run BUT when I tried to launch the game onto my pc, it said that there were duplicate definitions.

Is there an issue with the project linking with an older version dll or something?

Was it because you were writing it in the same namespace?

So the one in WidgetComponent reads

UUserWidget* UWidgetComponent::GetUserWidgetObject() const

If you’re writing UWidgetComponent:: just in another class, then that would probably be a duplicate definition.

This sounds like bad juju but have you tried renaming that function in your other .cpp file? I’d still rather just export the function as an external symbol using the UMG_API macro as it’s been proven to work.

I haven’t downloaded source… I should probably take the time do that since I am writing heavily in C++. heh.

I just though it was interesting that I didn’t receive a duplicate def. error when i run the code through VS, but when i try to launch the game, i’ll receive the error then.

My best guess is that when you’re compiling, it’s just your game module. When you’re loading the game, the UMG module is probably loaded as well.

Yea it took a while but downloading from source and then adding the UMG_API Macro to the WidgetComponent.h file then recompiling allowed me to use the function to get it working. It is a bit annoying as every one else on my team now needs my version of the engine but I am sure once the Unreal Team makes this non experimental they well add the macro. My game is also heavy c++ so this process was educational on the build process of the engine so regardless it was worth doing it.