/
EvilBeaver
/
OneScript
Обзор
Документация
Войти
/
EvilBeaver
/
OneScript
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
v2.0-alpha-1
src/OneScript.StandardLibrary/NativeApi/NativeApiLibrary.cs
82 строки
3 KB
Andrey Ovsiankin
Полностью переделана работа с типами (начало).
26 янв 2021, 17:56
26 янв 2021, 17:56
5d1c262
Код
Авторство
О чём код?
/*---------------------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using ScriptEngine.Machine; namespace OneScript.StandardLibrary.NativeApi { /// <summary> /// Класс, ассоциированный с экземпляром библиотеки внешних компонент /// Native API и осуществляющий непосредственное создание экземпляра компоненты. /// </summary> public class NativeApiLibrary : NativeApiKernel { private delegate IntPtr GetClassNames(); private readonly List<NativeApiComponent> _components = new List<NativeApiComponent>(); private readonly String _tempfile; public NativeApiLibrary(String filepath, String identifier) { using (var stream = File.OpenRead(filepath)) { if (NativeApiPackage.IsZip(stream)) { _tempfile = Path.GetTempFileName(); NativeApiPackage.Extract(stream, _tempfile); Module = LoadLibrary(_tempfile); } else Module = LoadLibrary(filepath); } if (Loaded) RegisterComponents(identifier); } public void Dispose() { foreach (var component in _components) component.Dispose(); if (Loaded && FreeLibrary(Module)) if (!String.IsNullOrEmpty(_tempfile)) try { File.Delete(_tempfile); } catch (Exception) { } } public IntPtr Module { get; private set; } = IntPtr.Zero; public Boolean Loaded { get => Module != IntPtr.Zero; } private void RegisterComponents(String identifier) { var funcPtr = GetProcAddress(Module, "GetClassNames"); if (funcPtr == IntPtr.Zero) throw new RuntimeException("В библиотеке внешних компонент не обнаружена функция: GetClassNames()"); var namesPtr = Marshal.GetDelegateForFunctionPointer<GetClassNames>(funcPtr)(); if (namesPtr == IntPtr.Zero) throw new RuntimeException("Не удалось получить список компонент в составе библиотеки"); var separator = new char[] { '|' }; var names = NativeApiProxy.Str(namesPtr).Split(separator, StringSplitOptions.RemoveEmptyEntries); foreach (String name in names) TypeManager.RegisterType($"AddIn.{identifier}.{name}", default, typeof(NativeApiFactory)); } public IValue CreateComponent(object host, String typeName, String componentName) { var component = new NativeApiComponent(host, this, typeName, componentName); _components.Add(component); return ValueFactory.Create(component); } } }