Unresolved external symbol when calling Custom Game Module

Hi,

I’ve been trying to figure out how make a custom library that I can share between projects.

While surfing the documentation it seems like the approach is to create a GameModule. So that’s what I did. I added the extra module names on my target.cs and also the public dependency on the primary game buid.cs. Everything seem to be working except the fact that I can’t use my GameModule from my game.

Im pretty new to unreal and have been more than ten years since I don’t use Cpp. Probably Im missing something naive.

This is how my Module looks like

using UnrealBuildTool;

public class ModuleA : ModuleRules
{
	public ModuleA(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
		Type = ModuleType.CPlusPlus;
			
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
		
		PrivateDependencyModuleNames.AddRange(new string[] {  });
		
		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}


//ModuleA.cpp
// Copyright Epic Games, Inc. All Rights Reserved.

#include "ModuleA.h"
#include "Modules/ModuleManager.h"

IMPLEMENT_GAME_MODULE( FDefaultGameModuleImpl, ModuleA)

TestModuleA.h
#pragma once
#include "CoreMinimal.h"

class UTestModuleA 
{
public:
    static void HelloWorld();
};

#include "TestModuleA.h"

//TestModuleA.cpp
#include "Engine.h"
#include "CoreMinimal.h"

void UTestModuleA::HelloWorld()
{
    UE_LOG(LogTemp, Log, TEXT("Hello form Module A"));
}

And Here where Im trying to use it (the project game name is PluginCreationPrj)

using UnrealBuildTool;

public class PluginCreationPrj : ModuleRules
{
	public PluginCreationPrj(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
		
			
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ModuleA" });
		PrivateDependencyModuleNames.AddRange(new string[] { "ModuleA" });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}

// Fill out your copyright notice in the Description page of Project Settings.


#include "PluginCreationPrj/Public/AMoveUp.h"

#include "ModuleA/TestModuleA.h"
// Sets default values
AAMoveUp::AAMoveUp()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AAMoveUp::BeginPlay()
{
	Super::BeginPlay();
	
}
int Sum10(int A)
{
	return A + 10;
}
// Called every frame
void AAMoveUp::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	auto Loc = GetActorLocation();
	SetActorLocation(Loc + FVector(0, 0, .05));
	
	UTestModuleA::HelloWorld(); //<-- The error is there. The IDE autocomplete though
	
}

EDIT:

Just figured out looking at the Engine’s source that if I add DLLEXPORT in front of the function it does work. Like so

class UTestModuleA 
{
public:
 DLLEXPORT static void HelloWorld();
};

Is there any other way to get this working without specifying it or even better, is it the correct approach for sharing code between projects?

Thanks,
Juan