Creating a module. Problem with definitions in *.cpp

Hello, community and devs,

I’m trying to implement a module. Take a look please what I have:


//TestModule.h - it's in TestModule/Public folder
#pragma once
#include "ModuleManager.h"

class FTestModule : public IModuleInterface
{
public:
	void Test();
};


//TestModule.cpp - it's in TestModule/Public folder too
#include "TestModule.h"

IMPLEMENT_MODULE(FTestModule, TestModule)

void FTestModule::Test(){};

Easy, isn’t it? Next, in MyProject.Build.cs I’ve added this module to PublicDependencyModuleNames list.

Now if I’ll run my game my module will be loaded (it’s shown in Developer Tools → Modules).

And now the most interesting part - in game code (in game mode constructor) I call


FTestModule test = FModuleManager::LoadModuleChecked< FTestModule >("TestModule");
//test.Test();

It works, game module creates. But when I uncomment a line I always get an error:


error LNK2019: unresolved external symbol "public: void __cdecl FTestModule::Test(void)" (?Test@FTestModule@@QEAAXXZ) referenced in function ...

Furthermore, if I remove definition from *.cpp and define a function in *.h everything works fine. Why?

Up. Sorry.

Reading a lot I found that this error can arise when I have a declaration, but not definition. But it’s clearly seen that I define the function in *.cpp. Furthermore, in the same *.cpp I call IMPLEMENT_MODULE, so this file is visible for linker. I tried to dump produced dll with dumpbin utility and didn’t find any information about my function.

The most sad part - I’m following buid-in UE4 modules (Analytics, for example) and somehow UE solution works but mine - not.

In development builds (on Windows) modules are built as dynamic libraries, that means any classes/methods/functions that you want to use outside that module must be explicitly exported from the module. For example:



class TESTMODULE_API FTestModule : public IModuleInterface
{ 
public:     
    void Test(); 
};


See the TESTMODULE_API? That will export the entire FTestModule class from your module, alternatively you can apply it to just a subset of methods in a class. MODULENAME_API is automatically defined for each module, where MODULENAME is the name of the module in all caps.

Hey, enlight_2014! Thank you for the answer. I’ve seen this MYMODULE_API requirement in some posts before. The difficult part to understand - why plugin tutorials (this, for example) have not such requirement. Or some UE modules (for example, Analytics) doesn’t have it.
Anyway, for my simple case this doesn’t help (. I don’t believe that I’m the first guy who trying to create a module. Maybe someone can share an example code or good explanation?

Upd.: today I’ve created new project from scratch, new module with MODULE_API declaration and everything works fine. But still I have one open question - how does build-in UE modules work without that?

If you look at the plugin tutorials you’ll notice that IModule only has inline and pure virtual methods, and its parent class IModuleInterface likewise only contains inline methods, there’s no need to export anything in order to use either of those classes in your project because all the relevant information is already in the header files. The same thing applies to UE modules that don’t use MODULE_API. In your case however, your FTestModule has a Test method that isn’t inline, nor pure virtual, which means that when you link your project against your module the linker is going to try and find the definition of that method in your module’s library. You can read more about the different ways to export classes from DLLs in this article.

Thank you very much. Now it’s clear.

Also see https://answers.unrealengine.com/questions/79230/creating-module-virtual-function-error.html