在Unlua中可使用以下宏来静态导出反射体系外的类、成员函数、成员变量、全局函数和枚举
/** * Export a class */ #define EXPORT_UNTYPED_CLASS(Name, bIsReflected, Lib) struct FExported##Name##Helper { static FExported##Name##Helper StaticInstance; FExported##Name##Helper() : ExportedClass(nullptr) { UnLua::IExportedClass *Class = UnLua::FindExportedClass(#Name); if (!Class) { ExportedClass = new UnLua::TExportedClassBase<bIsReflected>(#Name); UnLua::ExportClass(ExportedClass); Class = ExportedClass; } Class->AddLib(Lib); } ~FExported##Name##Helper() { delete ExportedClass; } UnLua::IExportedClass *ExportedClass; }; #define BEGIN_EXPORT_CLASS(Type, ...) \ BEGIN_EXPORT_NAMED_CLASS(Type, Type, ##__VA_ARGS__) #define BEGIN_EXPORT_NAMED_CLASS(Name, Type, ...) \ DEFINE_NAMED_TYPE(#Name, Type) BEGIN_EXPORT_CLASS_EX(false, Name, , Type, nullptr, ##__VA_ARGS__) #define BEGIN_EXPORT_REFLECTED_CLASS(Type, ...) \ BEGIN_EXPORT_CLASS_EX(true, Type, , Type, nullptr, ##__VA_ARGS__) #define BEGIN_EXPORT_CLASS_WITH_SUPER(Type, SuperType, ...) \ BEGIN_EXPORT_NAMED_CLASS_WITH_SUPER_NAME(Type, Type, #SuperType, ##__VA_ARGS__) #define BEGIN_EXPORT_NAMED_CLASS_WITH_SUPER_NAME(TypeName, Type, SuperTypeName, ...) \ DEFINE_NAMED_TYPE(#TypeName, Type) BEGIN_EXPORT_CLASS_EX(false, TypeName, , Type, SuperTypeName, ##__VA_ARGS__) #define BEGIN_EXPORT_CLASS_EX(bIsReflected, Name, Suffix, Type, SuperTypeName, ...) struct FExported##Name##Suffix##Helper { typedef Type ClassType; static FExported##Name##Suffix##Helper StaticInstance; UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__> *ExportedClass; ~FExported##Name##Suffix##Helper() { delete ExportedClass; } FExported##Name##Suffix##Helper() : ExportedClass(nullptr) { UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__> *Class = (UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__>*)UnLua::FindExportedClass(#Name); if (!Class) { ExportedClass = new UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__>(#Name, SuperTypeName); UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); Class = ExportedClass; } #define ADD_PROPERTY(Property) \ Class->AddProperty(#Property, &ClassType::Property); #define ADD_BITFIELD_BOOL_PROPERTY(Property) \ { uint8 Buffer[sizeof(ClassType)] = {0}; ((ClassType*)Buffer)->Property = 1; bool bSuccess = Class->AddBitFieldBoolProperty(#Property, Buffer); check(bSuccess); } #define ADD_FUNCTION(Function) \ Class->AddFunction(#Function, &ClassType::Function); #define ADD_NAMED_FUNCTION(Name, Function) \ Class->AddFunction(Name, &ClassType::Function); #define ADD_FUNCTION_EX(Name, RetType, Function, ...) \ Class->AddFunction<RetType, ##__VA_ARGS__>(Name, (RetType(ClassType::*)(__VA_ARGS__))(&ClassType::Function)); #define ADD_CONST_FUNCTION_EX(Name, RetType, Function, ...) \ Class->AddFunction<RetType, ##__VA_ARGS__>(Name, (RetType(ClassType::*)(__VA_ARGS__) const)(&ClassType::Function)); #define ADD_STATIC_FUNCTION(Function) \ Class->AddStaticFunction(#Function, &ClassType::Function); #define ADD_STATIC_FUNCTION_EX(Name, RetType, Function, ...) \ Class->AddStaticFunction<RetType, ##__VA_ARGS__>(Name, &ClassType::Function); #define ADD_EXTERNAL_FUNCTION(RetType, Function, ...) \ Class->AddStaticFunction<RetType, ##__VA_ARGS__>(#Function, Function); #define ADD_EXTERNAL_FUNCTION_EX(Name, RetType, Function, ...) \ Class->AddStaticFunction<RetType, ##__VA_ARGS__>(Name, Function); #define ADD_STATIC_CFUNTION(Function) \ Class->AddStaticCFunction(#Function, &ClassType::Function); #define ADD_NAMED_STATIC_CFUNTION(Name, Function) \ Class->AddStaticCFunction(Name, &ClassType::Function); #define ADD_LIB(Lib) \ Class->AddLib(Lib); #define ADD_SHARED_PTR_CONSTRUCTOR(Mode, ...) \ Class->AddSharedPtrConstructor<Mode, ##__VA_ARGS__>(); #define ADD_SHARED_REF_CONSTRUCTOR(Mode, ...) \ Class->AddSharedRefConstructor<Mode, ##__VA_ARGS__>(); #define END_EXPORT_CLASS(...) \ } }; #define IMPLEMENT_EXPORTED_CLASS(Name) \ FExported##Name##Helper FExported##Name##Helper::StaticInstance; #define IMPLEMENT_EXPORTED_CLASS_EX(Name, Suffix) \ FExported##Name##Suffix##Helper FExported##Name##Suffix##Helper::StaticInstance; /** * Export a global function */ #define EXPORT_FUNCTION(RetType, Function, ...) static struct FExportedFunc##Function : public UnLua::TExportedFunction<RetType, ##__VA_ARGS__> { FExportedFunc##Function(const FString &InName, RetType(*InFunc)(__VA_ARGS__)) : UnLua::TExportedFunction<RetType, ##__VA_ARGS__>(InName, InFunc) { UnLua::ExportFunction(this); } } Exported##Function(#Function, Function); #define EXPORT_FUNCTION_EX(Name, RetType, Function, ...) static struct FExportedFunc##Name : public UnLua::TExportedFunction<RetType, ##__VA_ARGS__> { FExportedFunc##Name(const FString &InName, RetType(*InFunc)(__VA_ARGS__)) : UnLua::TExportedFunction<RetType, ##__VA_ARGS__>(InName, InFunc) { UnLua::ExportFunction(this); } } Exported##Name(#Name, Function); /** * Export an enum */ #define BEGIN_EXPORT_ENUM(Enum) \ DEFINE_NAMED_TYPE(#Enum, Enum) static struct FExported##Enum : public UnLua::FExportedEnum { typedef Enum EnumType; FExported##Enum(const FString &InName) : UnLua::FExportedEnum(InName) { UnLua::ExportEnum(this); #define ADD_ENUM_VALUE(Value) \ NameValues.Add(#Value, Value); #define ADD_SCOPED_ENUM_VALUE(Value) \ NameValues.Add(#Value, (int32)EnumType::Value); #define END_EXPORT_ENUM(Enum) \ } } Exported##Enum(#Enum);
1. 宏BEGIN_EXPORT_REFLECTED_CLASS, END_EXPORT_CLASS放在任意.h/.cpp都行,需要include "UnLuaEx.h"
宏IMPLEMENT_EXPORTED_CLASS需要放在.cpp里。
2. 导出的函数参数、成员变量的类型必须为ue4反射支持的类型或者已被unlua静态导出过的类型
3. 模板函数要针对每一种类型,显式指定一个新名字函数名字,然后静态导出。
静态导出UnScoped enumeration(enum)
UnScoped枚举c++定义和导出
#include "UnLuaEx.h" // c++定义 typedef enum { SGSOUND_SFX = 0, SGSOUND_UI, SGSOUND_Max, }ESGSoundType; // 静态导出 BEGIN_EXPORT_ENUM(ESGSoundType) ADD_ENUM_VALUE(SGSOUND_SFX) ADD_ENUM_VALUE(SGSOUND_UI) END_EXPORT_ENUM(ESGSoundType) /* 静态导出 展开 template <> struct UnLua::TType<ESGSoundType, false> { static const char* GetName() { return "ESGSoundType"; } }; static struct FExportedESGSoundType : public UnLua::FExportedEnum { typedef ESGSoundType EnumType; FExportedESGSoundType(const FString& InName) : UnLua::FExportedEnum(InName) { UnLua::ExportEnum(this); NameValues.Add("SGSOUND_SFX", SGSOUND_SFX); NameValues.Add("SGSOUND_UI", SGSOUND_UI); } } ExportedESGSoundType("ESGSoundType"); */
导出的lua定义
---@class ESGSoundType ---@field public SGSOUND_SFX integer ---@field public SGSOUND_UI integer local ESGSoundType = {}
静态导出Scoped enumeration(enum class)
Scoped枚举c++定义和导出
#include "UnLuaEx.h" // c++定义 enum class ESWeaponType { SWEAPON_MAIN = 0, SWEAPON_PISTOL, SWEAPON_MELEE, SWEAPON_Max, }; // 静态导出 BEGIN_EXPORT_ENUM(ESWeaponType) ADD_SCOPED_ENUM_VALUE(SWEAPON_MAIN) ADD_SCOPED_ENUM_VALUE(SWEAPON_PISTOL) ADD_SCOPED_ENUM_VALUE(SWEAPON_MELEE) END_EXPORT_ENUM(ESWeaponType) /* 静态导出 展开 template <> struct UnLua::TType<ESWeaponType, false> { static const char* GetName() { return "ESWeaponType"; } }; static struct FExportedESWeaponType : public UnLua::FExportedEnum { typedef ESWeaponType EnumType; FExportedESWeaponType(const FString& InName) : UnLua::FExportedEnum(InName) { UnLua::ExportEnum(this); NameValues.Add("SWEAPON_MAIN", (int32)EnumType::SWEAPON_MAIN); NameValues.Add("SWEAPON_PISTOL", (int32)EnumType::SWEAPON_PISTOL); NameValues.Add("SWEAPON_MELEE", (int32)EnumType::SWEAPON_MELEE); } } ExportedESWeaponType("ESWeaponType"); */
导出的lua定义
---@class ESWeaponType ---@field public SWEAPON_MAIN integer ---@field public SWEAPON_PISTOL integer ---@field public SWEAPON_MELEE integer local ESWeaponType = {}
导出c++静态全局函数
c++定义和导出
#include "UnLuaEx.h" // c++定义 UUserWidget* CreateWidgetOwnedByPlayerController(APlayerController* OwningPlayerController, TSubclassOf<UUserWidget> UserWidgetClass = UUserWidget::StaticClass(), FName WidgetName = NAME_None) { return nullptr; } void ListenForInputActionEx(UUserWidget* Widget, FName ActionName, int32 EventType) { } EXPORT_FUNCTION(UUserWidget*, CreateWidgetOwnedByPlayerController, APlayerController*, TSubclassOf<UUserWidget>, FName) EXPORT_FUNCTION(void, ListenForInputActionEx, UUserWidget*, FName, int32) /* 静态导出 展开 static struct FExportedFuncCreateWidgetOwnedByPlayerController : public UnLua::TExportedFunction< UUserWidget*, APlayerController*, TSubclassOf<UUserWidget>, FName> { FExportedFuncCreateWidgetOwnedByPlayerController(const FString& InName, UUserWidget*(*InFunc)( APlayerController*, TSubclassOf<UUserWidget>, FName)) : UnLua::TExportedFunction<UUserWidget*, APlayerController*, TSubclassOf<UUserWidget>, FName>(InName, InFunc) { UnLua::ExportFunction(this); } } ExportedCreateWidgetOwnedByPlayerController("CreateWidgetOwnedByPlayerController", CreateWidgetOwnedByPlayerController); static struct FExportedFuncListenForInputActionEx : public UnLua::TExportedFunction<void, UUserWidget*, FName, int32> { FExportedFuncListenForInputActionEx(const FString& InName, void (*InFunc)(UUserWidget*, FName, int32)) : UnLua::TExportedFunction<void, UUserWidget*, FName, int32>(InName, InFunc) { UnLua::ExportFunction(this); } } ExportedListenForInputActionEx("ListenForInputActionEx", ListenForInputActionEx); */
导出的lua定义
---@param P0 APlayerController ---@param P1 TSubclassOf<UUserWidget> ---@param P2 string ---@return UUserWidget function _G.CreateWidgetOwnedByPlayerController(P0, P1, P2) end ---@param P0 UUserWidget ---@param P1 string ---@param P2 integer function _G.ListenForInputActionEx(P0, P1, P2) end
导出普通c++类的函数
c++定义和导出 注:如果有父类,需使用BEGIN_EXPORT_CLASS_WITH_SUPER(ClassType, SuperClassType)宏
#include "UnLuaEx.h" // c++定义 class LuaToolSet { public: static bool BatteryIsCharging() { return true; } static float GetBatteryLevel() {return 1;} static void ForceGarbageCollection(){} static FString FMD5HashAnsiString(const FString& str) { return TEXT(""); } static void GetProperyByClass(UObject* umg, TArray<UUserWidget*>& FoundWidgets, TSubclassOf<UUserWidget> WidgetClass){} static TArray<int64> GetTArrayInt64() { TArray<int64> Arr; Arr.Add(10); return Arr; } static int32 NativeGetWorldType(UWorld* World, bool IsClient) { return 0; } }; BEGIN_EXPORT_CLASS(LuaToolSet) ADD_FUNCTION(PlayMusic) ADD_FUNCTION(StopMusic) ADD_FUNCTION_EX("SetMusicVolume", bool, NativeSetMusicVolume, int, float) ADD_STATIC_FUNCTION(BatteryIsCharging) ADD_STATIC_FUNCTION(GetBatteryLevel) ADD_STATIC_FUNCTION(ForceGarbageCollection) ADD_STATIC_FUNCTION(FMD5HashAnsiString) ADD_STATIC_FUNCTION(GetProperyByClass) ADD_STATIC_FUNCTION(GetTArrayInt64) ADD_STATIC_FUNCTION_EX("GetWorldType", int32, NativeGetWorldType, UWorld*, bool) END_EXPORT_CLASS(LuaToolSet) IMPLEMENT_EXPORTED_CLASS(LuaToolSet) /* 静态导出 展开 template <> struct UnLua::TType<LuaToolSet, false> { static const char* GetName() { return "LuaToolSet"; } }; struct FExportedLuaToolSetHelper { typedef LuaToolSet ClassType; static FExportedLuaToolSetHelper StaticInstance; UnLua::TExportedClass<false, LuaToolSet>* ExportedClass; ~FExportedLuaToolSetHelper() { delete ExportedClass; } FExportedLuaToolSetHelper() : ExportedClass(nullptr) { UnLua::TExportedClass<false, LuaToolSet>* Class = (UnLua::TExportedClass<false, LuaToolSet>*) UnLua::FindExportedClass("LuaToolSet"); if (!Class) { ExportedClass = new UnLua::TExportedClass<false, LuaToolSet>("LuaToolSet", nullptr); UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); Class = ExportedClass; } Class->AddFunction("PlayMusic", &ClassType::PlayMusic); Class->AddFunction("StopMusic", &ClassType::StopMusic); Class->AddFunction<bool,int, float>("SetMusicVolume", (bool(ClassType::*)(int, float))(&ClassType::NativeSetMusicVolume)); Class->AddStaticFunction("BatteryIsCharging", &ClassType::BatteryIsCharging); Class->AddStaticFunction("GetBatteryLevel", &ClassType::GetBatteryLevel); Class->AddStaticFunction("ForceGarbageCollection", &ClassType::ForceGarbageCollection); Class->AddStaticFunction("FMD5HashAnsiString", &ClassType::FMD5HashAnsiString); Class->AddStaticFunction("GetProperyByClass", &ClassType::GetProperyByClass); Class->AddStaticFunction("GetTArrayInt64", &ClassType::GetTArrayInt64); Class->AddStaticFunction<int32,UWorld*, bool>("GetWorldType", &ClassType::NativeGetWorldType); } }; FExportedLuaToolSetHelper FExportedLuaToolSetHelper::StaticInstance; */
导出的lua定义
---@param P0 string function LuaToolSet:PlayMusic(P0) end function LuaToolSet:StopMusic() end ---@param P0 integer ---@param P1 number ---@return boolean function LuaToolSet:SetMusicVolume(P0, P1) end ---@return boolean function LuaToolSet.BatteryIsCharging() end ---@return number function LuaToolSet.GetBatteryLevel() end function LuaToolSet.ForceGarbageCollection() end ---@param P0 string ---@return string function LuaToolSet.FMD5HashAnsiString(P0) end ---@param P0 UObject ---@param P1 TArray<UUserWidget> @[out] ---@param P2 TSubclassOf<UUserWidget> function LuaToolSet.GetProperyByClass(P0, P1, P2) end ---@return TArray<integer> function LuaToolSet.GetTArrayInt64() end ---@param P0 UWorld ---@param P1 boolean ---@return integer function LuaToolSet.GetWorldType(P0, P1) end
导出ue4引擎反射类的属性和函数
c++导出
#include "UnLuaEx.h" // c++定义 BEGIN_EXPORT_REFLECTED_CLASS(UEngine)
// bool bIsInitialized; ADD_PROPERTY(bIsInitialized) // const FLinearColor& GetSelectedMaterialColor() const ADD_FUNCTION(GetSelectedMaterialColor) // void AddOnScreenDebugMessage(uint64 Key, float TimeToDisplay, FColor DisplayColor, const FString& DebugMessage, bool bNewerOnTop, const FVector2D& TextScale); ADD_FUNCTION_EX("AddDebugMessage", void, AddOnScreenDebugMessage, uint64, float, FColor, const FString&, bool, const FVector2D&) // static class UFont* GetSubtitleFont(); ADD_STATIC_FUNCTION(GetSubtitleFont) END_EXPORT_CLASS() IMPLEMENT_EXPORTED_CLASS(UEngine) /* 静态导出 展开 struct FExportedUEngineHelper { typedef UEngine ClassType; static FExportedUEngineHelper StaticInstance; UnLua::TExportedClass<true, UEngine>* ExportedClass; ~FExportedUEngineHelper() { delete ExportedClass; } FExportedUEngineHelper() : ExportedClass(nullptr) { UnLua::TExportedClass<true, UEngine>* Class = (UnLua::TExportedClass<true, UEngine>*) UnLua::FindExportedClass("UEngine"); if (!Class) { ExportedClass = new UnLua::TExportedClass<true, UEngine>("UEngine", nullptr); UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); Class = ExportedClass; } Class->AddProperty("bIsInitialized", &ClassType::bIsInitialized); Class->AddFunction("GetSelectedMaterialColor", &ClassType::GetSelectedMaterialColor); Class->AddFunction<void, uint64, float, FColor, const FString&, bool, const FVector2D&>( "AddDebugMessage", (void(ClassType::*)(uint64, float, FColor, const FString&, bool, const FVector2D&))(& ClassType::AddOnScreenDebugMessage)); Class->AddStaticFunction("GetSubtitleFont", &ClassType::GetSubtitleFont); } }; FExportedUEngineHelper FExportedUEngineHelper::StaticInstance;*/
导出的lua定义
// lua定义: ---@type boolean UEngine.bIsInitialized = nil ---@return FLinearColor function UEngine:GetSelectedMaterialColor() end ---@param P0 integer ---@param P1 number ---@param P2 FColor ---@param P3 string ---@param P4 boolean ---@param P5 FVector2D function UEngine:AddDebugMessage(P0, P1, P2, P3, P4, P5) end ---@return UFont function UEngine.GetSubtitleFont() end
通过AddLib方式导出反射类函数
c++导出
// c++定义 #include "UnLuaEx.h" static const luaL_Reg UClassLib[] = { { "Load", UClass_Load }, { "Find", UClass_Find }, { "IsChildOf", UClass_IsChildOf }, { nullptr, nullptr } }; BEGIN_EXPORT_REFLECTED_CLASS(UClass) ADD_LIB(UClassLib) END_EXPORT_CLASS() IMPLEMENT_EXPORTED_CLASS(UClass) /* 静态导出 展开 struct FExportedUClassHelper { typedef UClass ClassType; static FExportedUClassHelper StaticInstance; UnLua::TExportedClass<true, UClass>* ExportedClass; ~FExportedUClassHelper() { delete ExportedClass; } FExportedUClassHelper() : ExportedClass(nullptr) { UnLua::TExportedClass<true, UClass>* Class = (UnLua::TExportedClass<true, UClass>*) UnLua::FindExportedClass("UClass"); if (!Class) { ExportedClass = new UnLua::TExportedClass<true, UClass>("UClass", nullptr); UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); Class = ExportedClass; } Class->AddLib(UClassLib); } }; FExportedUClassHelper FExportedUClassHelper::StaticInstance;*/
导出的lua定义(IntelliSense不能识别AddLib方式,下面是自己加的)
// lua定义: ---@param P0 string ---@return UClass function UClass.Load(P0) end ---@param P0 string ---@return UClass function UClass.Find(P0) end ---@param P0 UObject ---@param P1 UObject ---@return bool function UClass.IsChildOf(P0, P1) end
导出自定义反射类的属性和函数
c++导出
// c++定义 #include "UnLuaEx.h" UCLASS() class MYGAME_API UMFPWObject : public UObject { GENERATED_BODY() public: int32 ObjectIndex; FString ObjectPath; uint8 bIsNative : 1; static int32 GetGlobalIndex() { return 100; } FString GetObjectPath() { return TEXT(""); } FString GetObjectHash() const { return TEXT(""); } FString QueryObject(int32 Index) { return TEXT(""); } bool operator==(const UMFPWObject& other) const { return true; } }; BEGIN_EXPORT_REFLECTED_CLASS(UMFPWObject) ADD_STATIC_FUNCTION(GetGlobalIndex) ADD_PROPERTY(ObjectIndex) ADD_PROPERTY(ObjectPath) ADD_BITFIELD_BOOL_PROPERTY(bIsNative) ADD_FUNCTION(GetObjectPath) ADD_CONST_FUNCTION_EX("GetObjectHashInLua", FString, GetObjectHash) ADD_FUNCTION_EX("QueryObjectInLua", FString, QueryObject, int32) ADD_NAMED_FUNCTION("Equals", operator==) END_EXPORT_CLASS() IMPLEMENT_EXPORTED_CLASS(UMFPWObject) /* 静态导出 展开 struct FExportedUMFPWObjectHelper { typedef UMFPWObject ClassType; static FExportedUMFPWObjectHelper StaticInstance; UnLua::TExportedClass<true, UMFPWObject>* ExportedClass; ~FExportedUMFPWObjectHelper() { delete ExportedClass; } FExportedUMFPWObjectHelper() : ExportedClass(nullptr) { UnLua::TExportedClass<true, UMFPWObject>* Class = (UnLua::TExportedClass<true, UMFPWObject>*) UnLua::FindExportedClass("UMFPWObject"); if (!Class) { ExportedClass = new UnLua::TExportedClass<true, UMFPWObject>("UMFPWObject", nullptr); UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); Class = ExportedClass; } Class->AddStaticFunction("GetGlobalIndex", &ClassType::GetGlobalIndex); Class->AddProperty("ObjectIndex", &ClassType::ObjectIndex); Class->AddProperty("ObjectPath", &ClassType::ObjectPath); { uint8 Buffer[sizeof(ClassType)] = {0}; ((ClassType*)Buffer)->bIsNative = 1; bool bSuccess = Class->AddBitFieldBoolProperty("bIsNative", Buffer); { if ((!(bSuccess))) { struct Impl { static void __declspec(noinline) __declspec(code_seg(".uedbg")) ExecCheckImplInternal() { FDebug::CheckVerifyFailed("bSuccess", "MFPWObject.cpp", 30, L""); } }; Impl::ExecCheckImplInternal(); (__nop(), __debugbreak());; } }; } Class->AddFunction("GetObjectPath", &ClassType::GetObjectPath); Class->AddFunction<FString>("GetObjectHashInLua", (FString(ClassType::*)() const)(&ClassType::GetObjectHash)); Class->AddFunction<FString,int32>("QueryObjectInLua", (FString(ClassType::*)(int32))(&ClassType::QueryObject)); Class->AddFunction("Equals", &ClassType::operator==); } }; FExportedUMFPWObjectHelper FExportedUMFPWObjectHelper::StaticInstance;*/
导出的lua定义
-- lua定义: ---@type integer UMFPWObject.ObjectIndex = nil ---@type string UMFPWObject.ObjectPath = nil ---@type boolean UMFPWObject.bIsNative = nil ---@return integer function UMFPWObject.GetGlobalIndex() end ---@return string function UMFPWObject:GetObjectPath() end ---@return string function UMFPWObject:GetObjectHashInLua() end ---@param P0 integer ---@return string function UMFPWObject:QueryObjectInLua(P0) end ---@param P0 UMFPWObject ---@return boolean function UMFPWObject:Equals(P0) end
导出避免符号冲突
在多个文件里对同一个类进行了静态导出回造成符号冲突,可以使用BEGIN_EXPORT_CLASS_EX宏
// file1.cpp BEGIN_EXPORT_CLASS_EX(true, UWorld, file1, UWorld, "UObject") //没有基类时,最后一个参数可以填nullptr ADD_FUNCTION(GetDefaultGravityZ) END_EXPORT_CLASS() IMPLEMENT_EXPORTED_CLASS_EX(UWorld, file1) // file2.cpp BEGIN_EXPORT_CLASS_EX(true, UWorld, file2, UWorld, "UObject") //没有基类时,最后一个参数可以填nullptr ADD_FUNCTION(GetMapName) END_EXPORT_CLASS() IMPLEMENT_EXPORTED_CLASS_EX(UWorld, file2)