UE4/C++: ジェネリック・プラットフォーム・罠ビリティー
諸事情により UE4 でゲームではない何かを開発したりユカイなマルチプロセスのゲームを作ったりすると プロセスID
を取得したくなるかもしれない。わたしはなった。
UE4 にはそんな時に便利そうな FGenericPlatform::GetCurrentProcessId
がある😃 プロセスIDを取得するためにクロスプラットフォームコードをちまちまOSごとに書く必要の無い理想郷がここにある。
さっそく実装しよう。
const auto pid = FGenericPlatform::GetCurrentProcessId(); UE_LOG( LogTemp, Log, TEXT( "pid=%d" ), pid )
しかしこの結果は常に、
0
となる。
驚きだろうか。私は一瞬驚いてソースコードを読みに行ってしまった。
// Runtime/Core/Private/GenericPlatform/GenericPlatformProcess.cpp uint32 FGenericPlatformProcess::GetCurrentProcessId() { // for single-process platforms (consoles, etc), just use 0 return 0; }
( ゚д゚)...
で、3秒くらいこの顔のまま考えて気づいた。『こっちじゃない』って。
// 『― ごめんね、ここはあなた( `Generic` )じゃダメなの ―』 // const auto pid = FGenericPlatform::GetCurrentProcessId(); // 『― あなたと、結合(リンク)したい! ―』 const auto pid = FPlatformProcess::GetCurrentProcessId(); UE_LOG( LogTemp, Log, TEXT( "pid=%d" ), pid )
FPlatform
は実質的に Unreal Engine API Reference でもアンドキュメントになってしまっているのだけど、
// Runtime/Core/Public/HAL/PlatformProcess.h #if PLATFORM_WINDOWS #include "Windows/WindowsPlatformProcess.h" #elif PLATFORM_PS4 #include "PS4/PS4Process.h" #elif PLATFORM_XBOXONE #include "XboxOne/XboxOneProcess.h" #elif PLATFORM_MAC #include "Mac/MacPlatformProcess.h" #elif PLATFORM_IOS #include "IOS/IOSPlatformProcess.h" #elif PLATFORM_ANDROID #include "Android/AndroidProcess.h" #elif PLATFORM_HTML5 #include "HTML5/HTML5PlatformProcess.h" #elif PLATFORM_LINUX #include "Linux/LinuxPlatformProcess.h" #elif PLATFORM_SWITCH #include "Switch/SwitchPlatformProcess.h" #endif
こんな具合に実装されていて、例えば Windows では
// Runtime/Core/Public/Windows/WindowsPlatformProcess.h struct CORE_API FWindowsPlatformProcess : public FGenericPlatformProcess // 中略 typedef FWindowsPlatformProcess FPlatformProcess;
と、なっていて、もちろんユーザープロジェクトからも他のエンジン実装のライブラリー群と同様に使用できる。
API Reference ドキュメントから機能を探してほぼ無意識にホイホイと実装してしまうと、うっかり FPlatformGenericProcess
ほか Generic 系を叩いてしまうのだけど、プラットフォームに依存性の高い機能は今回の GetCurrentProcessId
のように期待動作せず「( ゚д゚)」の3秒が訪れる事がある。
意識をしっかり保ちましょう。わたし、プログラマー( ・`ω・´)