天天看點

Unreal Engine 4:編譯打包Windows應用遇到的問題彙總

本文目的是将在Unreal Engine 4開發中遇到的一些問題及解決方案記錄下來,友善以後查找。

 版本:4.18

問題一:

在編譯如下代碼時:

UWidgetComponent* WidgetComponent = Cast<UWidgetComponent>(this->GetComponentByClass(UWidgetComponent::StaticClass()));
           

報如下錯誤:

error LNK2019: unresolved external symbol 
"__declspec(dllimport) private: static class UClass * __cdecl UWidgetComponent::GetPrivateStaticClass(void)"
 ([email protected]@@[email protected]@XZ) 
referenced in function "protected: virtual void __cdecl ATankModel::BeginPlay(void)" ([email protected]@@MEAAXXZ)
           

從錯誤資訊中看,好像是UWidgetComponent::GetPrivateStaticClass(void)方法未找到。但實際上UWidgetComponent中并不存在此方法。而此問題實際上是由于UWidgetComponent所在的子產品UMG,沒有加入到需要編譯的子產品中造成的。修改方式為在工程的.Build.cs檔案的編譯選項中添加此子產品:

using UnrealBuildTool;

public class ClientProj : ModuleRules
{
	public ClientProj(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

		PublicDependencyModuleNames.AddRange(
		    new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
    }
}
           

問題二:

在編譯如下代碼時:

template<typename T>
ValueBoxImpl<T>& getValueBox(std::shared_ptr<ValueBox> valueBox_ptr) {
	return dynamic_cast<ValueBoxImpl<T>&>(*valueBox_ptr);
};
           

報如下錯誤:

C:\Epic Games\UE_4.18\Engine\Source\Runtime\CoreUObject\Public\Templates/Casts.h(413): 
error C4541: 'dynamic_cast' used on polymorphic type 'tanx::ValueBox' with /GR-; 
unpredictable behavior may result
           

錯誤原因是RTTI未啟用,需要在.Build.cs檔案中啟用RTTI功能:

using UnrealBuildTool;

public class ClientProj : ModuleRules
{
	public ClientProj(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

		bUseRTTI = true;

		PublicDependencyModuleNames.AddRange(
		    new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
    }
}
           

問題三:

在編譯如下代碼時:

class GameHome {
private:
	AClientProjGameModeBase& gameMode;
}
           

報如下錯誤:

game_home.h(16): error C2143: syntax error: missing ';' before '&'
game_home.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
game_home.h(16): error C2238: unexpected token(s) preceding ';'
           

錯誤原因在于沒有在ATanxClientProjGameModeBase前加上class,修改後編譯通過:

class GameHome {
private:
	class AClientProjGameModeBase& gameMode;
}
           

從這個例子可以看到,從unreal提供的類作為父類衍生出的類,在使用時最好都加上class來修飾。

問題四:

編譯打包時報如下錯誤:

error C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
           

原因在于C++中使用了exception處理的機制。修改方法是在.Build.cs檔案中打開相關的編譯選項“bEnableExceptions”:

using UnrealBuildTool;

public class ClientProj : ModuleRules
{
	public ClientProj(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

		bUseRTTI = true;

		bEnableExceptions = true;

		PublicDependencyModuleNames.AddRange(
		    new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
    }
}
           

問題五:

在新開的線程中調用SpawnActor,應用會崩潰或什麼結果也沒有。

SpawnActor必須在game thread中被調用,如果不在game thread中被調用,可能會導緻系統自動退出。可以通過check(IsInGameThread());來檢測目前線程是否是game thread。

問題六:

在Plugins中設定了

bUseRTTI = true;

bEnableExceptions = true;

 結果打包Windows應用時,報如下警告和錯誤:

warning C4652: compiler option 'C++ Exception Handling Unwinding' inconsistent with precompiled header; current command-line option will override that defined in the precompiled header

warning C4651: '/D_HAS_EXCEPTIONS=0' specified for precompiled header but not for current compile

error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl std::bad_cast::bad_cast(char const *)"

造成此問題的原因是

UE_4.18\Engine\Intermediate\Build\Win64\UE4\Development\Engine\SharedPCH.Engine.RTTI.h

在編譯成

UE_4.18\Engine\Intermediate\Build\Win64\UE4\Development\Engine\SharedPCH.Engine.RTTI.h.pch

的過程中沒有設定bEnableExceptions = true;

需要修改UE_4.18\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildModuleCPP.cs

// 修改前
public PrecompiledHeaderInstance FindOrCreateSharedPCH(UEToolChain ToolChain, PrecompiledHeaderTemplate Template, bool bOptimizeCode, bool bUseRTTI, ActionGraph ActionGraph)

// 修改後
public PrecompiledHeaderInstance FindOrCreateSharedPCH(UEToolChain ToolChain, PrecompiledHeaderTemplate Template, bool bOptimizeCode, bool bUseRTTI, bool bEnableExceptions, ActionGraph ActionGraph)
           

并在此函數中添加

CompileEnvironment.bEnableExceptions = bEnableExceptions;
           

// 修改前
PrecompiledHeaderInstance Instance = FindOrCreateSharedPCH(ToolChain, Template, ModuleCompileEnvironment.bOptimizeCode, ModuleCompileEnvironment.bUseRTTI, ActionGraph); 


// 修改後
PrecompiledHeaderInstance Instance = FindOrCreateSharedPCH(ToolChain, Template, ModuleCompileEnvironment.bOptimizeCode, ModuleCompileEnvironment.bUseRTTI, ModuleCompileEnvironment.bEnableExceptions, ActionGraph); 
           

再編譯打包Windows應用時就不會報錯了。

繼續閱讀