mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Some more dotnet stuff
This commit is contained in:
@@ -27,16 +27,94 @@ namespace GlitchyEditor
|
|||||||
public ComponentEditWindow ComponentEditWindow => _componentEditWindow;
|
public ComponentEditWindow ComponentEditWindow => _componentEditWindow;
|
||||||
public SceneViewportWindow SceneViewportWindow => _sceneViewportWindow;
|
public SceneViewportWindow SceneViewportWindow => _sceneViewportWindow;
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
struct lib_args
|
||||||
|
{
|
||||||
|
public char16* Message;
|
||||||
|
public int32 number;
|
||||||
|
};
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
struct CreateInstanceArgs
|
||||||
|
{
|
||||||
|
//public StringView TypeName;
|
||||||
|
public char8* TypeName;
|
||||||
|
public int TypeNameLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ManagedReference;
|
||||||
|
|
||||||
|
public typealias CreateInstanceDelegate = function [CallingConvention(.Stdcall)] ManagedReference*(CreateInstanceArgs* arg, int32 arg_size_in_bytes);
|
||||||
|
|
||||||
|
public typealias FreeInstanceDelegate = function [CallingConvention(.Stdcall)] void(ManagedReference* arg);
|
||||||
|
|
||||||
|
public typealias InstanceMethodDelegate = function [CallingConvention(.Stdcall)] void(ManagedReference* arg);
|
||||||
|
|
||||||
/// Creates a new editor for the given world
|
/// Creates a new editor for the given world
|
||||||
public this(Scene scene)
|
public this(Scene scene)
|
||||||
{
|
{
|
||||||
String str = @"D:\Development\Projects\Beef\GlitchyEngine\build\Debug_Win64\GlitchyEditor\";
|
String str = @"D:\Development\Projects\Beef\GlitchyEngine\build\Debug_Win64\GlitchyEditor\";
|
||||||
|
//char16* ptr = str.ToScopedNativeWChar!();
|
||||||
|
|
||||||
char16* ptr = str.ToScopedNativeWChar!();
|
String runtimeConfig = scope String(str, "DotNetTest.runtimeconfig.json");
|
||||||
|
String assemblyPath = scope String(str, "DotNetTest.dll");
|
||||||
|
|
||||||
DotNetRuntime.Init();
|
DotNetRuntime.Init();
|
||||||
|
|
||||||
DotNetRuntime.TestRunDotNet(1, &ptr);
|
DotNetRuntime.LoadRuntime(runtimeConfig);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.Lib, DotNetTest", "Hello", let hello);
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.ScriptableEntity, DotNetTest", "Hello2", let hello2);
|
||||||
|
|
||||||
|
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.InteropHelper, DotNetTest", "Test", let test);
|
||||||
|
|
||||||
|
CreateInstanceDelegate createInstance;
|
||||||
|
//DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.InteropHelper, DotNetTest", "CreateInstance", "DotNetTest.InteropHelper+CreateInstanceEntryPoint, DotNetTest", out createInstance);
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.InteropHelper, DotNetTest", "CreateInstance", out createInstance);
|
||||||
|
|
||||||
|
FreeInstanceDelegate freeInstance;
|
||||||
|
//DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.InteropHelper, DotNetTest", "FreeInstance", "DotNetTest.InteropHelper+FreeInstanceEntryPoint, DotNetTest", out freeInstance);
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.InteropHelper, DotNetTest", "FreeInstance", out freeInstance);
|
||||||
|
|
||||||
|
InstanceMethodDelegate update;
|
||||||
|
//DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.ScriptableEntity, DotNetTest", "InvokeUpdate", "DotNetTest.ScriptableEntity+InstanceMethodEntryPoint, DotNetTest", out update);
|
||||||
|
DotNetRuntime.LoadAssemblyAndGetFunctionPointer(assemblyPath, "DotNetTest.ScriptableEntity, DotNetTest", "InvokeUpdate", out update);
|
||||||
|
|
||||||
|
//DotNetRuntime.TestRunDotNet(1, &ptr);
|
||||||
|
|
||||||
|
lib_args args = .
|
||||||
|
{
|
||||||
|
Message = "from host!".ToScopedNativeWChar!(),
|
||||||
|
number = 1337
|
||||||
|
};
|
||||||
|
|
||||||
|
hello(&args, sizeof(lib_args));
|
||||||
|
|
||||||
|
hello2(&args, sizeof(lib_args));
|
||||||
|
|
||||||
|
test(null, 0);
|
||||||
|
|
||||||
|
String typeName = "DotNetTest.ScriptableEntity, DotNetTest";
|
||||||
|
|
||||||
|
CreateInstanceArgs instanceArgs = .
|
||||||
|
{
|
||||||
|
TypeName = typeName.Ptr,
|
||||||
|
TypeNameLength = typeName.Length
|
||||||
|
};
|
||||||
|
|
||||||
|
ManagedReference* instance = createInstance(&instanceArgs, sizeof(CreateInstanceArgs));
|
||||||
|
|
||||||
|
for (int i < 10)
|
||||||
|
{
|
||||||
|
update(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeInstance(instance);
|
||||||
|
|
||||||
|
DotNetRuntime.Deinit();
|
||||||
|
|
||||||
_scene = scene;
|
_scene = scene;
|
||||||
_ecsWorld = _scene.[Friend]_ecsWorld;
|
_ecsWorld = _scene.[Friend]_ecsWorld;
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ StartupObject = "GlitchyEngineHelper.Program"
|
|||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
BuildCommandsOnCompile = "IfFilesChanged"
|
BuildCommandsOnCompile = "IfFilesChanged"
|
||||||
BuildCommandsOnRun = "IfFilesChanged"
|
BuildCommandsOnRun = "IfFilesChanged"
|
||||||
LibPaths = ["$(ProjectDir)/out/build/x64-debug/GlitchyEngineHelper.lib", "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEngineHelper\\vendor\\dotnethost\\nethost.lib"]
|
LibPaths = ["$(ProjectDir)/out/build/x64-debug/GlitchyEngineHelper.lib"]
|
||||||
PreBuildCmds = ["$(ProjectDir)\\..\\bin\\vscmake.bat x64 $(ProjectDir) x64-debug", "CopyToDependents(\"$(ProjectDir)/out/build/x64-debug/*.dll\")"]
|
PreBuildCmds = ["$(ProjectDir)\\..\\bin\\vscmake.bat x64 $(ProjectDir) x64-debug", "CopyToDependents(\"$(ProjectDir)/out/build/x64-debug/*.dll\")"]
|
||||||
|
|||||||
@@ -48,20 +48,43 @@ namespace
|
|||||||
hostfxr_get_runtime_delegate_fn get_delegate_fptr;
|
hostfxr_get_runtime_delegate_fn get_delegate_fptr;
|
||||||
hostfxr_close_fn close_fptr;
|
hostfxr_close_fn close_fptr;
|
||||||
|
|
||||||
|
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer;
|
||||||
|
|
||||||
|
hostfxr_handle hostContext;
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
bool load_hostfxr();
|
bool load_hostfxr();
|
||||||
load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t* assembly);
|
load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t* assembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
GE_EXPORT int GE_CALLTYPE DotNet_Init()
|
struct lib_args
|
||||||
{
|
{
|
||||||
if (!load_hostfxr())
|
const char_t* message;
|
||||||
{
|
int number;
|
||||||
assert(false && "Failure: load_hostfxr()");
|
};
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
typedef void (CORECLR_DELEGATE_CALLTYPE* custom_entry_point_fn)(lib_args args);
|
||||||
|
|
||||||
|
custom_entry_point_fn GetFunctionPointer(load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer, const string_t& dotnetlib_path, const char_t* dotnet_type, const char_t* method_name)
|
||||||
|
{
|
||||||
|
// Function pointer to managed delegate with non-default signature
|
||||||
|
custom_entry_point_fn custom = nullptr;
|
||||||
|
int rc = load_assembly_and_get_function_pointer(
|
||||||
|
dotnetlib_path.c_str(),
|
||||||
|
dotnet_type,
|
||||||
|
STR("CustomEntryPointUnmanaged") /*method_name*/,
|
||||||
|
UNMANAGEDCALLERSONLY_METHOD,
|
||||||
|
nullptr,
|
||||||
|
(void**)&custom);
|
||||||
|
assert(rc == 0 && custom != nullptr && "Failure: load_assembly_and_get_function_pointer()");
|
||||||
|
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadRuntime(const char_t* configPath)
|
||||||
|
{
|
||||||
|
load_assembly_and_get_function_pointer = get_dotnet_load_assembly(configPath);
|
||||||
|
assert(load_assembly_and_get_function_pointer != nullptr && "Failure: get_dotnet_load_assembly()");
|
||||||
}
|
}
|
||||||
|
|
||||||
GE_EXPORT int GE_CALLTYPE TestRunDotNet(int argc, wchar_t* argv[])
|
GE_EXPORT int GE_CALLTYPE TestRunDotNet(int argc, wchar_t* argv[])
|
||||||
@@ -121,11 +144,11 @@ GE_EXPORT int GE_CALLTYPE TestRunDotNet(int argc, wchar_t* argv[])
|
|||||||
//
|
//
|
||||||
// STEP 4: Run managed code
|
// STEP 4: Run managed code
|
||||||
//
|
//
|
||||||
struct lib_args
|
/*struct lib_args
|
||||||
{
|
{
|
||||||
const char_t* message;
|
const char_t* message;
|
||||||
int number;
|
int number;
|
||||||
};
|
};*/
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
// <SnippetCallManaged>
|
// <SnippetCallManaged>
|
||||||
@@ -140,18 +163,24 @@ GE_EXPORT int GE_CALLTYPE TestRunDotNet(int argc, wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function pointer to managed delegate with non-default signature
|
// Function pointer to managed delegate with non-default signature
|
||||||
typedef void (CORECLR_DELEGATE_CALLTYPE* custom_entry_point_fn)(lib_args args);
|
//typedef void (CORECLR_DELEGATE_CALLTYPE* custom_entry_point_fn)(lib_args args);
|
||||||
custom_entry_point_fn custom = nullptr;
|
//custom_entry_point_fn custom = nullptr;
|
||||||
rc = load_assembly_and_get_function_pointer(
|
//rc = load_assembly_and_get_function_pointer(
|
||||||
dotnetlib_path.c_str(),
|
// dotnetlib_path.c_str(),
|
||||||
dotnet_type,
|
// dotnet_type,
|
||||||
STR("CustomEntryPointUnmanaged") /*method_name*/,
|
// STR("CustomEntryPointUnmanaged") /*method_name*/,
|
||||||
UNMANAGEDCALLERSONLY_METHOD,
|
// UNMANAGEDCALLERSONLY_METHOD,
|
||||||
nullptr,
|
// nullptr,
|
||||||
(void**)&custom);
|
// (void**)&custom);
|
||||||
assert(rc == 0 && custom != nullptr && "Failure: load_assembly_and_get_function_pointer()");
|
//assert(rc == 0 && custom != nullptr && "Failure: load_assembly_and_get_function_pointer()");
|
||||||
|
|
||||||
lib_args args
|
custom_entry_point_fn custom = GetFunctionPointer(
|
||||||
|
load_assembly_and_get_function_pointer,
|
||||||
|
dotnetlib_path,
|
||||||
|
dotnet_type,
|
||||||
|
STR("CustomEntryPointUnmanaged") /*method_name*/);
|
||||||
|
|
||||||
|
lib_args args
|
||||||
{
|
{
|
||||||
STR("from host!"),
|
STR("from host!"),
|
||||||
-1
|
-1
|
||||||
@@ -227,25 +256,65 @@ namespace
|
|||||||
{
|
{
|
||||||
// Load .NET Core
|
// Load .NET Core
|
||||||
void* load_assembly_and_get_function_pointer = nullptr;
|
void* load_assembly_and_get_function_pointer = nullptr;
|
||||||
hostfxr_handle cxt = nullptr;
|
hostContext = nullptr;
|
||||||
int rc = init_fptr(config_path, nullptr, &cxt);
|
int rc = init_fptr(config_path, nullptr, &hostContext);
|
||||||
if (rc != 0 || cxt == nullptr)
|
if (rc != 0 || hostContext == nullptr)
|
||||||
{
|
{
|
||||||
std::cerr << "Init failed: " << std::hex << std::showbase << rc << std::endl;
|
std::cerr << "Init failed: " << std::hex << std::showbase << rc << std::endl;
|
||||||
close_fptr(cxt);
|
close_fptr(hostContext);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the load assembly function pointer
|
// Get the load assembly function pointer
|
||||||
rc = get_delegate_fptr(
|
rc = get_delegate_fptr(
|
||||||
cxt,
|
hostContext,
|
||||||
hdt_load_assembly_and_get_function_pointer,
|
hdt_load_assembly_and_get_function_pointer,
|
||||||
&load_assembly_and_get_function_pointer);
|
&load_assembly_and_get_function_pointer);
|
||||||
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
|
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
|
||||||
std::cerr << "Get delegate failed: " << std::hex << std::showbase << rc << std::endl;
|
std::cerr << "Get delegate failed: " << std::hex << std::showbase << rc << std::endl;
|
||||||
|
|
||||||
close_fptr(cxt);
|
// TODO: close_fptr(hostContext); ???
|
||||||
return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer;
|
return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer;
|
||||||
}
|
}
|
||||||
// </SnippetInitialize>
|
// </SnippetInitialize>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GE_EXPORT int GE_CALLTYPE DotNet_Init()
|
||||||
|
{
|
||||||
|
if (!load_hostfxr())
|
||||||
|
{
|
||||||
|
assert(false && "Failure: load_hostfxr()");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE_EXPORT int GE_CALLTYPE DotNet_Deinit()
|
||||||
|
{
|
||||||
|
int result = close_fptr(hostContext);
|
||||||
|
hostContext = nullptr;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE_EXPORT void GE_CALLTYPE DotNet_LoadRuntime(const char_t* configPath)
|
||||||
|
{
|
||||||
|
LoadRuntime(configPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
GE_EXPORT int GE_CALLTYPE DotNet_LoadAssemblyAndGetFunctionPointer(const char_t* assemblyPath, const char_t* typeName, const char_t* methodName, const char_t* delegateTypeName, void** outDelegate)
|
||||||
|
{
|
||||||
|
int rc = load_assembly_and_get_function_pointer(
|
||||||
|
assemblyPath,
|
||||||
|
typeName,
|
||||||
|
methodName,
|
||||||
|
delegateTypeName,
|
||||||
|
nullptr,
|
||||||
|
outDelegate);
|
||||||
|
|
||||||
|
assert(rc == 0 && outDelegate != nullptr && "Failure: load_assembly_and_get_function_pointer()");
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,75 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Interop;
|
using System.Interop;
|
||||||
|
|
||||||
namespace GlitchyEngineHelper
|
namespace GlitchyEngineHelper
|
||||||
{
|
{
|
||||||
static class DotNetRuntime
|
static class DotNetRuntime
|
||||||
{
|
{
|
||||||
[LinkName("TestRunDotNet"), CallingConvention(.Cdecl)]
|
[LinkName("TestRunDotNet"), CallingConvention(.Cdecl)]
|
||||||
public static extern int TestRunDotNet(c_int argc, c_wchar** argv);
|
public static extern c_int TestRunDotNet(c_int argc, c_wchar** argv);
|
||||||
|
|
||||||
[LinkName("DotNet_Init"), CallingConvention(.Cdecl)]
|
[LinkName("DotNet_Init"), CallingConvention(.Cdecl)]
|
||||||
public static extern int Init();
|
public static extern c_int Init();
|
||||||
|
|
||||||
|
[LinkName("DotNet_Deinit"), CallingConvention(.Cdecl)]
|
||||||
|
public static extern c_int Deinit();
|
||||||
|
|
||||||
|
[LinkName("DotNet_LoadRuntime"), CallingConvention(.Cdecl)]
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
private static extern void Internal_LoadRuntime(char16* configPath);
|
||||||
|
#else
|
||||||
|
private static extern void Internal_LoadRuntime(char8* configPath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static void LoadRuntime(StringView configPath)
|
||||||
|
{
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
Internal_LoadRuntime(configPath.ToScopedNativeWChar!());
|
||||||
|
#else
|
||||||
|
Internal_LoadRuntime(configPath.Ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[LinkName("DotNet_LoadAssemblyAndGetFunctionPointer"), CallingConvention(.Cdecl)]
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
private static extern c_int DotNet_LoadAssemblyAndGetFunctionPointer(char16* assemblyPath, char16* typeName, char16* methodName, char16* delegateName, void** outDelegate);
|
||||||
|
#else
|
||||||
|
private static extern c_int DotNet_LoadAssemblyAndGetFunctionPointer(char8* assemblyPath, char8* typeName, char8* methodName, char8* delegateName, void** outDelegate);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public typealias ManagedDelegate = function int32(void *arg, int32 arg_size_in_bytes);
|
||||||
|
|
||||||
|
public static c_int LoadAssemblyAndGetFunctionPointer(StringView assemblyPath, StringView typeName, StringView methodName, out ManagedDelegate outDelegate)
|
||||||
|
{
|
||||||
|
outDelegate = ?;
|
||||||
|
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
return DotNet_LoadAssemblyAndGetFunctionPointer(assemblyPath.ToScopedNativeWChar!(), typeName.ToScopedNativeWChar!(), methodName.ToScopedNativeWChar!(), null, (void**)&outDelegate);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static c_int LoadAssemblyAndGetFunctionPointer<T>(StringView assemblyPath, StringView typeName, StringView methodName, StringView delegateName, out T outDelegate) where T : var
|
||||||
|
{
|
||||||
|
outDelegate = ?;
|
||||||
|
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
return DotNet_LoadAssemblyAndGetFunctionPointer(assemblyPath.ToScopedNativeWChar!(), typeName.ToScopedNativeWChar!(), methodName.ToScopedNativeWChar!(), delegateName.ToScopedNativeWChar!(), (void**)&outDelegate);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static c_int LoadAssemblyAndGetFunctionPointer<T>(StringView assemblyPath, StringView typeName, StringView methodName, out T outDelegate) where T : var
|
||||||
|
{
|
||||||
|
outDelegate = ?;
|
||||||
|
|
||||||
|
#if BF_PLATFORM_WINDOWS
|
||||||
|
return DotNet_LoadAssemblyAndGetFunctionPointer(assemblyPath.ToScopedNativeWChar!(), typeName.ToScopedNativeWChar!(), methodName.ToScopedNativeWChar!(), (char16*)(void*)-1, (void**)&outDelegate);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user