diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 9ee57e3cd..b1f4948d3 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1036,7 +1036,7 @@ namespace FlaxEngine private static Dictionary assemblyHandles = new(); private static Dictionary loadedNativeLibraries = new(); - private static Dictionary nativeLibraryPaths = new(); + internal static Dictionary nativeLibraryPaths = new(); private static Dictionary assemblyOwnedNativeLibraries = new(); internal static AssemblyLoadContext scriptingAssemblyLoadContext; diff --git a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp b/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp index e50df903a..bdd9d04c6 100644 --- a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp +++ b/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +#include "Engine/Platform/Platform.h" #include "Engine/Animations/Graph/AnimGraph.h" #include "Engine/Scripting/InternalCalls.h" #include "Engine/Scripting/MException.h" diff --git a/Source/Engine/Tests/TestScripting.cpp b/Source/Engine/Tests/TestScripting.cpp index ce921412d..9df7d10a6 100644 --- a/Source/Engine/Tests/TestScripting.cpp +++ b/Source/Engine/Tests/TestScripting.cpp @@ -2,6 +2,9 @@ #include "TestScripting.h" #include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" #include TestClassNative::TestClassNative(const SpawnParams& params) @@ -11,6 +14,18 @@ TestClassNative::TestClassNative(const SpawnParams& params) TEST_CASE("Scripting") { + SECTION("Test Library Imports") + { + MClass* klass = Scripting::FindClass("FlaxEngine.Tests.TestScripting"); + CHECK(klass); + MMethod* method = klass->GetMethod("TestLibraryImports"); + CHECK(method); + MObject* result = method->Invoke(nullptr, nullptr, nullptr); + CHECK(result); + int32 resultValue = MUtils::Unbox(result); + CHECK(resultValue == 0); + } + SECTION("Test Class") { // Test native class diff --git a/Source/Engine/Tests/TestScripting.cs b/Source/Engine/Tests/TestScripting.cs index 917a9e567..62541742d 100644 --- a/Source/Engine/Tests/TestScripting.cs +++ b/Source/Engine/Tests/TestScripting.cs @@ -1,5 +1,49 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace FlaxEngine.Tests +{ + /// + /// Tests for scripting. + /// + public class TestScripting + { + /// + /// Tests all usages in the engine to verify all bindigns are correct to work with P/Invoke. + /// + public static int TestLibraryImports() + { + var result = 0; + var libraryName = "FlaxEngine"; + var library = NativeLibrary.Load(NativeInterop.nativeLibraryPaths[libraryName]); + if (library == IntPtr.Zero) + return -1; + var types = typeof(FlaxEngine.Object).Assembly.GetTypes(); + foreach (var type in types) + { + var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + foreach (var method in methods) + { + var libraryImport = method.GetCustomAttribute(); + if (libraryImport == null || libraryImport.LibraryName != libraryName || libraryImport.EntryPoint == null) + continue; + bool found = NativeLibrary.TryGetExport(library, libraryImport.EntryPoint, out var addr); + if (!found) + { + Debug.LogError("Missing library import: " + libraryImport.EntryPoint); + result++; + } + } + } + NativeLibrary.Free(library); + return result; + } + } +} + namespace FlaxEngine { partial struct TestStruct : System.IEquatable