It’s tricky. The engine and C# world are initializing on a different thread, so you’re not guaranteed that C# world even exists at this point in time. Furthermore, multiple activation requests can come in succession and you don’t want to lose any of them. I think the best solution here is to setup both a callback and multiple state storage. Something like this.
.cpp file in your Unity Project:
#include <string>
#include <vector>
#include <windows.h>
struct CriticalSection
{
inline CriticalSection()
{
InitializeCriticalSectionAndSpinCount(&m_CriticalSection, 200);
}
inline ~CriticalSection()
{
DeleteCriticalSection(&m_CriticalSection);
}
inline void Enter()
{
EnterCriticalSection(&m_CriticalSection);
}
inline void Leave()
{
LeaveCriticalSection(&m_CriticalSection);
}
struct Lock
{
inline Lock(CriticalSection& criticalSection) :
m_CriticalSection(criticalSection)
{
criticalSection.Enter();
}
inline ~Lock()
{
m_CriticalSection.Leave();
}
private:
CriticalSection& m_CriticalSection;
};
private:
CRITICAL_SECTION m_CriticalSection;
};
typedef void(__stdcall* ActivatedEventCallback)(const wchar_t* uri);
static CriticalSection s_CriticalSection;
static std::vector<std::wstring> s_ActivationUriBacklog;
static ActivatedEventCallback s_ActivatedEventCallback;
extern "C" void __stdcall SetupActivatedEventCallback(ActivatedEventCallback callback)
{
CriticalSection::Lock lock(s_CriticalSection);
s_ActivatedEventCallback = callback;
for (const auto& uri : s_ActivationUriBacklog)
s_ActivatedEventCallback(uri.c_str());
s_ActivationUriBacklog.clear();
}
__declspec(dllexport) void ReceivedResponse(const wchar_t* uri)
{
CriticalSection::Lock lock(s_CriticalSection);
if (s_ActivatedEventCallback != nullptr)
{
s_ActivatedEventCallback(uri);
}
else
{
s_ActivationUriBacklog.emplace_back(uri);
}
}
And then on your Unity project side in C#, you’d do this:
delegate void ReceivedResponseDelegate([MarshalAs(UnmanagedType.LPWStr)]string uri);
[MonoPInvokeCallback(typeof(ReceivedResponseDelegate))]
static void ReceivedResponse(string uri)
{
// Your code
}
[DllImport("__Internal")]
extern static void SetupActivatedEventCallback(ReceivedResponseDelegate callback);
void Awake()
{
SetupActivatedEventCallback(ReceivedResponse);
}
Finally, on the VS side, you just have to declare and call that function:
__declspec(dllimport) void ReceivedResponse(const wchar_t* uri);
ReceivedResponse(eventArgs->Uri->ToString()->Data());