Linker error when trying to instantiate UMaterialExpressionSubtract (possibly due to missing MinimalAPI keyword)

I’ve been trying to instantiate UMaterialExpressionSubtract from editor plugin and have been unable to do so due to linker error:

error LNK2019: unresolved external symbol "private: static class UClass * __cdecl UMaterialExpressionSubtract::GetPrivateStaticClass(wchar_t const *)" (?GetPrivateStaticClass@UMaterialExpressionSubtract@@CAPEAVUClass@@PEB_W@Z) referenced in function "public: static class UClass * __cdecl UMaterialExpressionSubtract::StaticClass(void)" (?StaticClass@UMaterialExpressionSubtract@@SAPEAVUClass@@XZ)

I’ve investigated the header and foudn out that its UCLASS macro is missing MinimalAPI keyword. That’s probably the cause of this problem.

Example:

MaterialExpressionAdd:

UCLASS(MinimalAPI)
class UMaterialExpressionAdd : public UMaterialExpression
{

MaterialExpressionMultiply:

UCLASS(MinimalAPI)
class UMaterialExpressionMultiply : public UMaterialExpression
{

MaterialExpressionSubtract:

UCLASS()
class UMaterialExpressionSubtract : public UMaterialExpression
{

I’m using Windows 7 64bit, with unreal engine 4.10.1

Hey NegInfinity-

Did you add an include statement for UMaterialExpressionSubtract? Did you mark the UMaterialExpressionSubtract with the UPROPERTY() macro? If possible, could you post what your setup looks like for using UMaterialExpressionSubtract?

Cheers

Yes, I did include it. If I didn’t, I would get compiler error instead of linker error.

The setup was literally:

UMaterialExpressionSubtract *smoothToRough = NewObject(material);

That line alone caused linker error I posted above.
Using UMaterialExpressionAdd instead of UMaterialExpressionSubtract worked fine.

The code was called from plugin.

I searched through the code/libraries, thought that maybe I forgot to include/specify anything, nope. It is specifically triggered by UMaterialExpressionSubtract. I think that’s because this class doesn’t have MinimalAPI keyword in class declaration.

It is possible that it cannot find the necessary dependency for UMaterialExpressionSubtract inside the plugin. Can you try setting “Engine” (with quotes) inside PublicDependencyModuleNames.AddRange(…) of the Plugin.Build.cs? Let me know if this helps or if you get a different error message.

That does not explain why it can find dependencies for UMaterialExpressionAdd and UMaterialExpressionMultiply. Those are located in the same folder as UMaterialExpressionSubtract.

“Engine” is within plugin’s Private dependencies.

Adding it to public, results in in the same link error.

error LNK2019: unresolved external symbol "private: static class UClass * __cdecl UMaterialExpressionSubtract::GetPrivateStaticClass(wchar_t const *)" (?GetPrivateStaticClass@UMaterialExpressionSubtract@@CAPEAVUClass@@PEB_W@Z)

Private section:

	PrivateDependencyModuleNames.AddRange(
		new string[]
		{
			"Projects",
			"InputCore",
			"UnrealEd",
			"LevelEditor",
			"CoreUObject",
			"Engine",
			"Slate",
			"SlateCore",
			"Json",
			"DesktopPlatform", 
			"RawMesh",
			"MaterialEditor",
			"AssetTools"
			// ... add private dependencies that you statically link with here ...	
		}
		);

Basically:

auto tmpNode1 = NewObject<UMaterialExpressionAdd>(material);
material->Expressions.Add(tmpNode1);
//auto tmpNode2 = NewObject<UMaterialExpressionSubtract>(material);
//material->Expressions.Add(tmpNode2);

Compiles and links without errors, but this:

auto tmpNode1 = NewObject<UMaterialExpressionAdd>(material);
material->Expressions.Add(tmpNode1);
auto tmpNode2 = NewObject<UMaterialExpressionSubtract>(material);
material->Expressions.Add(tmpNode2);

Causes linker error:

  error LNK2019: unresolved external symbol "private: static class UClass * __cdecl UMaterialExpressionSubtract::GetPrivateStaticClass(wchar_t const *)" (?GetPrivateStaticClass@UMaterialExpressionSubtract@@CAPEAVUClass@@PEB_W@Z)

Have you checked headers for those classes, by the way/ I already mentioned that the difference between UMaterialExpressionAdd and UMaterialExpresionSubtract is that *Add has MinimalAPI keyword, while *subtract doesn’t.

I checked github, apparently the MinimalAPI problem has been fixed by branch merge that happened on September 24:
[CL 2704241 by Jurre deBaare in Main branch]
There’s specifically line that adds “MinimalAPI” to UMaterialExpressionSubtract.
In my local cloned branch (4.10.1) UMaterialExpressionSubtract doesn’t ahve MinimalAPI key.

i’m not sure if 4.10.1 was released before 24th of september, though.

I also haven’t checked if upgrading the engine to the latest version fixes the issue (not enough HDD space at the moment).

Hey NegInfinity-

When adding UMaterialExpressionSubtract* Multi; along with an include to a plugin I did not get a LNK error. I did get other errors that caused the compile to fail that do not block compile for other project specific classes. I have submitted a bug report (UE-28678) to investigate this build failure issue. Also let me know if upgrading to 4.11 fixes your specific issue.

Cheers