Download

I can't seem to use a TArray in a plugin without generating an Unresolved External Symbol error

So, I have 2 plugins – “Dungeon Maker” and “State Machine.” Dungeon Maker has a dependency on the State Machine plugin, which is reflected in the .uplugin file:


      "Modules": 
        {
          "Name": "DungeonMaker",
          "Type": "Developer",
          "LoadingPhase": "Default"
        }
      ],
      "Plugins": 
        {
          "Name": "StateMachine",
          "Enabled": true
        }
      ]

and the .build.cs file:


    PrivateDependencyModuleNames.AddRange(
        new string]
        {
            "CoreUObject",
            "Engine",
            "Slate",
            "SlateCore",
            "StateMachine",
        }
    );

One of the things I’m trying to access is the FGrammarResult struct, which is defined as so:


    USTRUCT(BlueprintType)
    struct STATEMACHINE_API FGrammarResult
    {
        GENERATED_BODY()
    public:
        UPROPERTY(EditAnywhere, BlueprintReadOnly)
        const UGrammar* Grammar;
        UPROPERTY(EditAnywhere, BlueprintReadOnly)
        const UStateMachineState* NextState;

        UPROPERTY(EditAnywhere, BlueprintReadWrite)
        EGrammarResultType GrammarResult;

        UPROPERTY(EditAnywhere, BlueprintReadOnly)
        TArray<UGrammarAlphabet*> GrammarInputShape;
    };

As you can see, STATEMACHINE_API is in the struct definition. However, my project still fails to compile. This is the output from the linker:


    2>Module.DungeonMaker.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl FGrammarResult::FGrammarResult(void)" (__imp_??0FGrammarResult@@QEAA@XZ) referenced in function "protected: void __cdecl UDungeonMissionGenerator::TryToCreateDungeon(class UDungeonMissionNode *,class TArray<class UDungeonMissionGrammar const *,class FDefaultAllocator>,struct FRandomStream &,int)" (?TryToCreateDungeon@UDungeonMissionGenerator@@IEAAXPEAVUDungeonMissionNode@@V?$TArray@PEBVUDungeonMissionGrammar@@VFDefaultAllocator@@@@AEAUFRandomStream@@H@Z)
    2>Module.DungeonMaker.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl FGrammarResult::~FGrammarResult(void)" (__imp_??1FGrammarResult@@QEAA@XZ) referenced in function "protected: void __cdecl UDungeonMissionGenerator::TryToCreateDungeon(class UDungeonMissionNode *,class TArray<class UDungeonMissionGrammar const *,class FDefaultAllocator>,struct FRandomStream &,int)" (?TryToCreateDungeon@UDungeonMissionGenerator@@IEAAXPEAVUDungeonMissionNode@@V?$TArray@PEBVUDungeonMissionGrammar@@VFDefaultAllocator@@@@AEAUFRandomStream@@H@Z)
    2>Module.DungeonMaker.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl FGrammarResult::FGrammarResult(struct FGrammarResult const &)" (__imp_??0FGrammarResult@@QEAA@AEBU0@@Z) referenced in function "protected: void __cdecl UDungeonMissionGenerator::TryToCreateDungeon(class UDungeonMissionNode *,class TArray<class UDungeonMissionGrammar const *,class FDefaultAllocator>,struct FRandomStream &,int)" (?TryToCreateDungeon@UDungeonMissionGenerator@@IEAAXPEAVUDungeonMissionNode@@V?$TArray@PEBVUDungeonMissionGrammar@@VFDefaultAllocator@@@@AEAUFRandomStream@@H@Z)

What’s really weird is that it only happens when using a TArray. The following compiles just fine:


        UPROPERTY(EditAnywhere, BlueprintReadOnly)
        UGrammarAlphabet* GrammarInputShape;

It’s not just limited to UGrammarAlphabet, either. Even what’s below causes an unresolved external:


        UPROPERTY(EditAnywhere, BlueprintReadOnly)
        TArray<UObject*> GrammarInputShape;

This is driving me nuts. Even if I use TArray<int32>, I get an Unresolved External Symbol. There is no reason why it would work fine without the TArray, but then suddenly making it into an array causes an unresolved external. Even including “Containers/Array.h” doesn’t fix it.

TSet and TMap run into the same issue, as does TSubclassOf, which is leading me to think it’s some issue to do with templates, but I can’t even begin to think about how to fix this.

What gives?

It seems, by the linker error, that you have to define a default constructor, copy constructor and destructor for the FGrammarResult struct