Linker error for ULandscapeSplineSegment::GetLocalMeshComponents() while other functions from EXACT there work

Hi everyone!

I am having a hard time with landscape splines and just can’t figure out a linker error here.

I am having an Actor, which has this function:


void AAIPath::GenerateSplines(ULandscapeSplinesComponent* SourceSpline,
                              FExtraAISplineMetaDataStruct MetaDataToAdd = FExtraAISplineMetaDataStruct{}) const
{

	...

		//iterate over all segments again
		for (const TObjectPtr<ULandscapeSplineSegment> Segment : SourceSpline->GetSegments())
		{
			//this also gives linker error
			//Segment->SupportsForeignSplineMesh();
                        //while this works:
                        //Segment->UpdateSplinePoints();

			TArray<USplineMeshComponent*> test = Segment->GetLocalMeshComponents(); //ERROR
	...
		}
	}
}

I want to find out the colission box of the mesh later, but for now I just want to get the Mesh component at this segment. The interesting part here is, that “ULandscapeSplineSegment::GetLocalMeshComponents()” ends in

error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "“public: class TArray<class USplineMeshComponent *,class TSizedDefaultAllocator<32> > __cdecl ULandscapeSplineSegment::GetLocalMeshComponents(void)const " (?GetLocalMeshComponents@ULandscapeSplineSegment@@QEBA?AV?$TArray@PEAVUSplineMeshComponent@@V?$TSizedDefaultAllocator@$0CA@@@@@XZ)” in Funktion "“public: void __cdecl AAIPath::GenerateSplines(class ULandscapeSplinesComponent *,struct FExtraAISplineMetaDataStruct)const " (?GenerateSplines@AAIPath@@QEBAXPEAVULandscapeSplinesComponent@@UFExtraAISplineMetaDataStruct@@@Z)”.
1>C:\Projects\Unreal\a2racermvpNew\Binaries\Win64\UnrealEditor-A2RacerMVP.dll : fatal error LNK1120: 1 nicht aufgelöste Externe

while other functions like “ULandscapeSplineSegment::UpdateSplinePoints()” work. So the includes and modules seem to work. Any ideas about that? I am really lost here, what it could be. If we look into “LandscapeSplineSegment.h” they literally look the same:

TArray<USplineMeshComponent*> GetLocalMeshComponents() const;

virtual void UpdateSplinePoints(bool bUpdateCollision = true, bool bUpdateMeshLevel = false);

Also the c++ (LandscapeSplines.cpp) seems “boring” regarding that:

TArray<USplineMeshComponent*> ULandscapeSplineSegment::GetLocalMeshComponents() const
{
	return LocalMeshComponents;
}

Finally this is the member in the header:

	/** Spline meshes */
	UPROPERTY(TextExportTransient)
	TArray<TObjectPtr<USplineMeshComponent>> LocalMeshComponents;

Anyone can help me? Thank you so much!

UPDATE:
When I add “virtual” to the function the linker issues is gone. I absolutely do NOT understand why and it is not acceptable to change source code of UE for that. Anyone here who can explain to me why this happens and what other workaround might exist?

UPDATE2:
Seems the meshes I search live in “SplineMeshes”, so acces might be better with

TArray test = Segment->SplineMeshes;

I guess.

I know this is frustrating, let me break it down for you. As you’ve spotted, UpdateSplinePoints can be callied because it is marked as virtual.

This is happening because marking the function as virtual adds it to the class vtable, making it accessible to other modules. To be more precise, non-pure (with implementation) virtual functions can be called without being exported however you will be using the base class implementation - in this example this is fine because no derived class changes implementation.

This is why other functions (like GetForeignMeshComponents) have the LANDSCAPE_API which properly exports the functions. (Note: this can also be done at the class level and will export all the publicly available functions).