diff --git a/csharp-api/REFrameworkNET/API.cpp b/csharp-api/REFrameworkNET/API.cpp index 55e4d01bd..64fe3dc08 100644 --- a/csharp-api/REFrameworkNET/API.cpp +++ b/csharp-api/REFrameworkNET/API.cpp @@ -17,6 +17,11 @@ REFrameworkNET::API::API(uintptr_t param) void REFrameworkNET::API::Init_Internal(const REFrameworkPluginInitializeParam* param) { + if (s_api != nullptr) { + Console::WriteLine("REFrameworkNET.API Init_Internal called but API is already initialized."); + return; + } + Console::WriteLine("REFrameworkNET.API Init_Internal called."); s_api = reframework::API::initialize(param).get(); Callbacks::Impl::Setup(this); diff --git a/csharp-api/REFrameworkNET/Callbacks.cpp b/csharp-api/REFrameworkNET/Callbacks.cpp index 4bcf17a62..7c3e4ebc1 100644 --- a/csharp-api/REFrameworkNET/Callbacks.cpp +++ b/csharp-api/REFrameworkNET/Callbacks.cpp @@ -3,10 +3,19 @@ #include "Callbacks.hpp" using namespace System; +using namespace System::Runtime::InteropServices; +using namespace System::Collections::Generic; namespace REFrameworkNET { namespace Callbacks { void Impl::Setup(REFrameworkNET::API^ api) { + if (s_setup) { + Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks called but already setup."); + return; + } + + s_setup = true; + Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks called."); reframework::API* nativeApi = api->GetNativeImplementation(); @@ -23,20 +32,26 @@ void Impl::Setup(REFrameworkNET::API^ api) { continue; } - if (type->GetField("FUNCTION_PRE_CALLBACK_ADDRESS") == nullptr) { - continue; - } + const auto wantedFlags = System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::Static; - if (type->GetField("FUNCTION_POST_CALLBACK_ADDRESS") == nullptr) { + if (type->GetField("TriggerPostDelegate", wantedFlags) == nullptr || type->GetField("TriggerPreDelegate", wantedFlags) == nullptr) { continue; } auto eventName = type->Name; auto eventNameStr = msclr::interop::marshal_as(eventName); - auto eventHandlerPre = (uintptr_t)type->GetField("FUNCTION_PRE_CALLBACK_ADDRESS")->GetValue(nullptr); - auto eventHandlerPost = (uintptr_t)type->GetField("FUNCTION_POST_CALLBACK_ADDRESS")->GetValue(nullptr); - nativeApi->param()->functions->on_pre_application_entry(eventNameStr.c_str(), (REFOnPreApplicationEntryCb)eventHandlerPre); - nativeApi->param()->functions->on_post_application_entry(eventNameStr.c_str(), (REFOnPostApplicationEntryCb)eventHandlerPost); + auto triggerPost = type->GetField("TriggerPostDelegate", wantedFlags)->GetValue(nullptr); + auto triggerPre = type->GetField("TriggerPreDelegate", wantedFlags)->GetValue(nullptr); + + if (triggerPre == nullptr || triggerPost == nullptr) { + System::Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks: TriggerPreDelegate or TriggerPostDelegate is null for " + eventName); + continue; + } + + IntPtr preHookPtr = Marshal::GetFunctionPointerForDelegate(triggerPre); + IntPtr postHookPtr = Marshal::GetFunctionPointerForDelegate(triggerPost); + nativeApi->param()->functions->on_pre_application_entry(eventNameStr.c_str(), (REFOnPreApplicationEntryCb)preHookPtr.ToPointer()); + nativeApi->param()->functions->on_post_application_entry(eventNameStr.c_str(), (REFOnPostApplicationEntryCb)postHookPtr.ToPointer()); } } } diff --git a/csharp-api/REFrameworkNET/Callbacks.hpp b/csharp-api/REFrameworkNET/Callbacks.hpp index 5845c816b..01a8fd0c5 100644 --- a/csharp-api/REFrameworkNET/Callbacks.hpp +++ b/csharp-api/REFrameworkNET/Callbacks.hpp @@ -8,41 +8,26 @@ using namespace System::Collections::Generic; namespace REFrameworkNET { ref class API; +public ref class BaseCallback { +public: + delegate void Delegate(); +}; + #define GENERATE_POCKET_CLASS(EVENT_NAME) \ -static void EVENT_NAME##PreHandler_Internal(); \ -static void EVENT_NAME##PostHandler_Internal(); \ public ref class EVENT_NAME { \ public: \ - delegate void Delegate(); \ - static event Delegate^ Pre; \ - static event Delegate^ Post; \ + static event BaseCallback::Delegate^ Pre; \ + static event BaseCallback::Delegate^ Post; \ +internal: \ static void TriggerPre() { \ Pre(); \ } \ static void TriggerPost() { \ Post(); \ } \ - static System::Reflection::MethodInfo^ TriggerPreMethod = nullptr;\ - static System::Reflection::MethodInfo^ TriggerPostMethod = nullptr;\ - static uintptr_t FUNCTION_PRE_CALLBACK_ADDRESS = (uintptr_t)&EVENT_NAME##PreHandler_Internal; \ - static uintptr_t FUNCTION_POST_CALLBACK_ADDRESS = (uintptr_t)&EVENT_NAME##PostHandler_Internal; \ + static BaseCallback::Delegate^ TriggerPreDelegate = gcnew BaseCallback::Delegate(&EVENT_NAME::TriggerPre); \ + static BaseCallback::Delegate^ TriggerPostDelegate = gcnew BaseCallback::Delegate(&EVENT_NAME::TriggerPost); \ }; \ -void EVENT_NAME##PreHandler_Internal() { \ - if (Callbacks::##EVENT_NAME::TriggerPreMethod == nullptr) { \ - auto self = System::Reflection::Assembly::LoadFrom(System::Reflection::Assembly::GetExecutingAssembly()->Location); \ - auto type = self->GetType("REFrameworkNET.Callbacks." #EVENT_NAME); \ - Callbacks::##EVENT_NAME::TriggerPreMethod = type->GetMethod("TriggerPre", System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public); \ - } \ - Callbacks::##EVENT_NAME::TriggerPreMethod->Invoke(nullptr, nullptr); \ -} \ -void EVENT_NAME##PostHandler_Internal() { \ - if (Callbacks::##EVENT_NAME::TriggerPostMethod == nullptr) { \ - auto self = System::Reflection::Assembly::LoadFrom(System::Reflection::Assembly::GetExecutingAssembly()->Location); \ - auto type = self->GetType("REFrameworkNET.Callbacks." #EVENT_NAME); \ - Callbacks::##EVENT_NAME::TriggerPostMethod = type->GetMethod("TriggerPost", System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public); \ - } \ - Callbacks::##EVENT_NAME::TriggerPostMethod->Invoke(nullptr, nullptr); \ -} namespace Callbacks { GENERATE_POCKET_CLASS(Initialize) @@ -425,6 +410,9 @@ namespace Callbacks { public ref class Impl { public: static void Setup(REFrameworkNET::API^ api); + + private: + static bool s_setup = false; }; }; } \ No newline at end of file