忘记改啥了*1

This commit is contained in:
fengjiayi
2024-11-02 16:48:40 +08:00
parent 0088d32f12
commit cd1642dcf7
45 changed files with 1022 additions and 447 deletions

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Threading.Tasks;
namespace Serein.NodeFlow.Tool
{
/// <summary>
/// 管理加载在流程的程序集
/// </summary>
public class FlowLibraryLoader : AssemblyLoadContext
{
private Assembly _pluginAssembly;
/// <summary>
/// 加载程序集
/// </summary>
/// <param name="pluginPath"></param>
public FlowLibraryLoader(string pluginPath) : base(isCollectible: true)
{
_pluginAssembly = LoadFromAssemblyPath(pluginPath);
}
/// <summary>
/// 保持默认加载行为
/// </summary>
/// <param name="assemblyName"></param>
/// <returns></returns>
protected override Assembly Load(AssemblyName assemblyName)
{
return null; // 保持默认加载行为
}
/// <summary>
/// 是否对程序集的引用
/// </summary>
public void UnloadPlugin()
{
_pluginAssembly = null; // 释放对程序集的引用
Unload(); // 触发卸载
// 强制进行垃圾回收,以便完成卸载
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}

View File

@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Serein.NodeFlow.Tool
{
internal class NativeDllHelper
{
// 引入 Windows API 函数
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
// 引入 Unix/Linux 的动态库加载函数
[DllImport("libdl.so.2", SetLastError = true)]
private static extern IntPtr dlopen(string filename, int flag);
[DllImport("libdl.so.2", SetLastError = true)]
private static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("libdl.so.2", SetLastError = true)]
private static extern int dlclose(IntPtr handle);
private const int RTLD_NOW = 2;
// bool LoadDll(string file)
// void LoadAllDll(string path, bool isRecurrence = true);
private static List<IntPtr> Nints = new List<nint>();
/// <summary>
/// 加载单个Dll
/// </summary>
/// <param name="file"></param>
public static bool LoadDll(string file)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return LoadWindowsLibrarie(file);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return LoadLinuxLibrarie(file);
}
else
{
Console.WriteLine("Unsupported OS.");
return false;
}
}
public static void LoadAllDll(string path, bool isRecurrence = true)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
foreach (var file in Directory.GetFiles(path, "*.dll"))
{
LoadWindowsLibrarie(file);
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
foreach (var file in Directory.GetFiles(path, "*.so"))
{
LoadLinuxLibrarie(file);
}
}
else
{
Console.WriteLine("Unsupported OS.");
}
foreach (var dir in Directory.GetDirectories(path))
{
LoadAllDll(dir, true);
}
}
/// <summary>
/// 加载Windows类库
/// </summary>
/// <param name="path"></param>
/// <param name="isRecurrence">是否递归加载</param>
private static bool LoadWindowsLibrarie(string file)
{
IntPtr hModule = IntPtr.Zero;
try
{
hModule = LoadLibrary(file);
// 加载 DLL
if (hModule != IntPtr.Zero)
{
Nints.Add(hModule);
Console.WriteLine($"Loaded: {file}");
return true;
}
else
{
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading {file}: {ex.Message}");
return false;
}
}
/// <summary>
/// 加载Linux类库
/// </summary>
/// <param name="file"></param>
private static bool LoadLinuxLibrarie(string file)
{
IntPtr handle = IntPtr.Zero;
try
{
handle = dlopen(file, RTLD_NOW);
if (handle != IntPtr.Zero)
{
Nints.Add(handle);
Console.WriteLine($"Loaded: {file}");
return true;
// 可以调用共享库中的函数
// IntPtr procAddress = dlsym(handle, "my_function");
}
else
{
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading {file}: {ex.Message}");
return false;
}
}
/// <summary>
/// 卸载所有已加载DLL
/// </summary>
public static void FreeLibrarys()
{
for (int i = 0; i < Nints.Count; i++)
{
IntPtr hModule = Nints[i];
FreeLibrary(hModule);
}
Nints.Clear();
}
}
}

View File

@@ -174,11 +174,11 @@ public static class NodeMethodDetailsHelper
ConvertorInstance[key] = (instance, convertMethod);
}
Func<object, object> func = (enumValue) =>
object func(object enumValue)
{
(var obj,var methodInfo) = ConvertorInstance[key];
(var obj, var methodInfo) = ConvertorInstance[key];
return methodInfo?.Invoke(obj, [enumValue]);
};
}
// 确保实例实现了所需接口
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true, func);
@@ -206,26 +206,29 @@ public static class NodeMethodDetailsHelper
}
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
int index,
Type paremType,
bool isExplicitData,
Func<object, object> func = null)
int index,
Type paremType,
bool isExplicitData,
Func<object, object> func = null)
{
bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数
string explicitTypeName = GetExplicitTypeName(paremType);
var items = GetExplicitItems(paremType, explicitTypeName);
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
return new ParameterDetails
{
IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
Index = index,
ExplicitTypeName = explicitTypeName,
ExplicitType = paremType,
Convertor = func,
DataType = parameterInfo.ParameterType,
Index = index, // 索引
ExplicitTypeName = explicitTypeName, // Select/Bool/Value
ExplicitType = paremType,// 显示的入参类型
Convertor = func, // 转换器
DataType = parameterInfo.ParameterType, // 实际的入参类型
Name = parameterInfo.Name,
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量
IsParams = hasParams, // 判断是否为可变参数
};
}