Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84

Исполнение функций подгружаемых во время исполнения программы из сторонних хранилищ

22.08.2016, 11:05. Показов 2473. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
День добрый, отзывчивые, знающие, смекалистые.
Не знаю как чётко сформулировать вопрос, поэтому опишу как смогу, надеюсь поймёте.(Опытным программистам к таким постановкам проблем не привыкать )
Язык C#.
Предположим что есть программа, которая по своей сути является оболочкой без особого функционала, но с пользовательским интерфесом (форма с полями ввода и кнопками). И вот эта программа, должна смотреть в определённом месте все файлы нами заданного типа. (пофиг каком, пусть папка с именем LibSrc которая рядом с экзешником самой программы лежит). Файлы эти по своей "структуре" однотипные, но по содержанию разные. Содержат эти файлы только функции. Причём функции только типа
C#
1
bool FuncNx(ref byte[][] args, ref String ReturnNameThisFuntion)
Если файлом ПОТРЕБУЕТСЯ для решения проблеммы ещё что-то содержать - это нормально и допустимо.
Программа же должна по желанию пользователся должна выдать список всех доступных функций из этих файлов и иметь возможность запускать выбранную пользователем из этого списка функцию с параметрами (котоыре все вида byte[][] args)
Собственно вопрос, какой сущьностью должны быть эти файлы с функциями? Библиотеками, сериализованными экземплярами класса или ещё чемто? И собственно как это должно работать?
Писать код не прошу(хотя и приветствую) но меня больше интересует сам подход и общая идея.
Варианты подходаЖ:
Была идея сделать эти файлы в виде DLL, но собственно как работать с данной конкретной библиотекой остаётся непонятным - самой программе же чтбы подгрузить библиотеку и воспользоваться функциями из неё нужно же знать имена этих функций, не так ли? Можно конечно в каждую такую длл ку засунуть функцию типа
C#
1
bool GiveMeYourFuncsList(ref List<DelegateMy> FuncList)
где
public delegate bool DelegateMy(ref byte[][] args, ref String ReturnNameThisFuntion);
Тоесть в каждой библиотеке есть функция с одним и темже именем которая возвращает лист с указателем на все её функции. Но я не уверен что такое вобще реализуемо, не пробовал, просто мысль.

Другая идея это каждый такой вот файл будет не DLL а сохраненный сериализованный класс(экземпляр?!), который является наследником от некоторого класса, который позволил бы организовать взаимодействие программы с нашей программой, но в каждом таком классе переопределены функции и их коичество(!), однако количество функций указано в виде константного поля.

Ваши коментарии, пожалуйста.

Добавлено через 2 минуты
Вы хоть маякните если "что автор хотел то вобще?! он сам то понял? я нет!"
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.08.2016, 11:05
Ответы с готовыми решениями:

Объединить вместе несколько сторонних облачных хранилищ
Подскажите, есть ли open-source программы, с помощью которых можно было бы объединить вместе несколько сторонних облачных хранилищ....

Ошибки во время исполнения программы
Приветствую всех форумчян. Во время исполнения программы система выдает 2 ошибки (см. вложения). Кто сталкивался с такими? Чем они...

Разное время исполнения программы
&quot;Баловался&quot; с кодом питона и наткнулся на интересный результат: один и тот же код выполняется разное время. Почему так? Понятно, что...

23
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
22.08.2016, 12:13
Лучший ответ Сообщение было отмечено JustOneQuestion как решение

Решение

Здравствуйте!

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Была идея сделать эти файлы в виде DLL
Это, на мой взгляд, наиболее простой вариант для реализации.

Загрузить сборку можно при помощи методов Assembly.Load*.

Список доступных функций можно получить перечислив все типы в загруженной сборке, а затем получив методы типов.

C#
1
var functionMap = assembly.GetTypes().ToDictionary(t => t, t => t.GetMethods());
При необходимости методы можно отфильтровать, взяв только подходящие по сигнатуре.

Вызов методов можно осуществить с использованием функции MethodInfo.Invoke.
Если методы не статические, то для вызова потребуется создать экземпляр типа, в котором находится метод.
Сделать это можно возпользовавшись функционалом класса Activator. Пример:

C#
1
var instance = Activator.CreateInstance(functionMap.Keys.First());

Другой решения - компиляция кода на лету будет значительно сложней в реализации и поддержке.
1
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
22.08.2016, 15:40  [ТС]
golubyatnikovtv, спасибо за совет, пробую сделать как вы предложили.
Пара вопросов появилась
1.
C#
1
Type[] Types = SampleAssembly.GetTypes();
Тут под Type подразумеваются классы? или ещё что-то может быть? Если в DLL-ке будет только один класс то этот массив будет состоять только из одного элемента?
2.
C#
1
MethodInfo[] Methods = SampleAssembly.GetTypes()[0].GetMethods();
Вроде как возвращает список тех самых функций что описаны в классе + стандартные 4 штуки типа GetString() и т д.
Вы предложили отфильтровать по сигнатуре. Вот тут вот чёт даже идей нет как это сделать. Не подскажите?
3. Это всё работает на XP?

А так конечно да... впечетляет...
0
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
22.08.2016, 16:01
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Тут под Type подразумеваются классы?
Да, классы, т.е. все объявленные в сборке типы.

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
или ещё что-то может быть?
Могут еще быть анонимные типы... их нужно будет отфильтровать.
Проверить на анонимность можно так http://stackoverflow.com/a/2483054

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Если в DLL-ке будет только один класс то этот массив будет состоять только из одного элемента?
Да, если анонимных типов не будет.

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Вы предложили отфильтровать по сигнатуре. Вот тут вот чёт даже идей нет как это сделать. Не подскажите?
Если, ничего лишнего в сборке не планируется, и, например, все функции с такой сигнатурой
C#
1
bool FuncNx(ref byte[][] args, ref String ReturnNameThisFuntion)
, то достаточно проверить элементарные вещи:
1) MethodInfo.ReturnType == typeof(bool)
2) MethodInfo.GetParameters().Length == 2

Если этого будет не достаточно то также нужно проверить сами параметры получаемые функцией GetParameters()


Под .NET Framework 4.0 должно все работать.
1
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
22.08.2016, 16:26  [ТС]
А, ну хорошо. Через MethodInfo.GetParameters() идея понятна, можно и так. Я просто думал что есть какоето волшебный лямбда код в одну строчку и какойнить способ выкинуть из листа всё что неудоволетворяет определнёным требованиям, которые собственно в лямда коде бы и были указаны. В таком варианте это была бы одна строка. Но это не критично )

Вызов методов можно осуществить с использованием функции MethodInfo.Invoke.
Если методы не статические, то для вызова потребуется создать экземпляр типа, в котором находится метод.
Сделать это можно возпользовавшись функционалом класса Activator. Пример:
Вот тут тоже вопрос, Казалось бы можно же сделать статические функции, делать их иными смысла же вроде нет?
Если они будут статическими, то какие варианты вызова могут быть и что предпочтительнее?
0
Эксперт .NET
 Аватар для Rius
13114 / 7675 / 1674
Регистрация: 25.05.2015
Сообщений: 23,403
Записей в блоге: 14
22.08.2016, 16:28
JustOneQuestion, C# .Net + WindowsForms + плагины
0
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
22.08.2016, 16:31
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Я просто думал что есть какоето волшебный лямбда код в одну строчку и какойнить способ выкинуть из листа всё что неудоволетворяет определнёным требованиям, которые собственно в лямда коде бы и были указаны.
Можно и в лямбде сделать те проверки, которые я написал. Без разницы.

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Казалось бы можно же сделать статические функции, делать их иными смысла же вроде нет?
Не знаю специфику... не могу ответить.

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Если они будут статическими, то какие варианты вызова могут быть и что предпочтительнее?
Тогда экземпляр класса создавать не надо будет, а в качестве первого параметра метода Invoke передать null.
0
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
23.08.2016, 13:03  [ТС]
golubyatnikovtv, Rius спасибо за советы.
Я вот не пойму а как сделать в
C#
1
MethodInfo.Invoke(Object obj,   Object[] parameters)
C#
1
MethodInfo.Invoke(Object obj,   ref Object[] parameters)
чтобы результат работы не в возвращаемое значение засовывался, а именно ссылка передавалась и работа шла с уже созданным объектом.
К Activator.CreateInstance тот же вопрос.

Не знаю специфику... не могу ответить.
Всмысле я имел ввиду не "как МНЕ сделать лучше в программе", а если в проекте нет разницы создать статические методы класса или статический класс или вобще без статики, то с точки зрения (в общем случае) использования DLL как было бы предпочтительнее?
0
Эксперт .NET
 Аватар для Rius
13114 / 7675 / 1674
Регистрация: 25.05.2015
Сообщений: 23,403
Записей в блоге: 14
23.08.2016, 13:20
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
с точки зрения (в общем случае) использования DLL как было бы предпочтительнее?
Применить интерфейс плагинов и не париться рефлексией.

Потом идёт MAF/MEF. Навороченнее, якобы гибче, тормознее.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.08.2016, 13:33
Цитата Сообщение от Rius Посмотреть сообщение
Потом идёт MAF/MEF. Навороченнее, якобы гибче, тормознее.
JustOneQuestion, если у вас не 100500 плагинов, то действительно используйте MEF и не заморачивайтесь с рефлексией. Он проще, и вполне может решить все ваши проблемы.
0
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
23.08.2016, 13:53
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
чтобы результат работы не в возвращаемое значение засовывался, а именно ссылка передавалась и работа шла с уже созданным объектом.
Здесь хороший ответ http://stackoverflow.com/a/8779751

Цитата Сообщение от JustOneQuestion Посмотреть сообщение
К Activator.CreateInstance тот же вопрос
Если Вы статические методы сделаете, то не нужно будет создавать инстанс типа.
"Тот же вопрос" мне не понятен применительно к активатору.

Цитата Сообщение от Rius Посмотреть сообщение
Применить интерфейс плагинов и не париться рефлексией.
На мой взгляд, перед тем как работать с плагинами, нужно разобраться с рефлексией. Стоит попариться.

Добавлено через 15 минут
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Всмысле я имел ввиду не "как МНЕ сделать лучше в программе", а если в проекте нет разницы создать статические методы класса или статический класс или вобще без статики, то с точки зрения (в общем случае) использования DLL как было бы предпочтительнее?
Обычно статику лучше избегать. ООП ведь не зря имеет в своем названии "объектно-ориентированное". Т.е. предполагается работа с объектами. Много статики делает код хуже тестируемым. Не позволяет "подменить" функциональность, как можно сделать с механизмами внедрения зависимостей, наследованием и др. Таким образом, принцип "инверсии зависимостей" из SOLID становится неприменимым.
0
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
23.08.2016, 16:37  [ТС]
Спасибо всем за советы, Если четсно не понял в чём же сложность рефлексии, подскажите где ждать подвоха.
Спасибо, с ref разобрался.
Вроде принцип работы с вытаскиванием функций из DLL понятен ... в общих чертах. Дальше посмотрим.

Есть ещё один вопрос в моём сознании. Наврено его сформулировать можно так: Можно ли "скопировать" метод вытащенный из DLL и вставить его в мной созданный некий класс так, чтобы после одноразовой загрузки DLL, вытаскивания из неё метода, можно было забыть про DLL и больше с ней не взаимодействовать. А метод при этом уже будет методом уже моего какогото класса и чтобы его выполнить я буду обращаться к нему через экземпляр класса.
0
Эксперт .NET
 Аватар для Rius
13114 / 7675 / 1674
Регистрация: 25.05.2015
Сообщений: 23,403
Записей в блоге: 14
23.08.2016, 17:16
JustOneQuestion, она не сложная и без подвоха.
Зато она излишняя и слишком подробная. Вам придётся описывать все мелочи на низком уровне. Это трудозатратно, муторно, долго.
В отличие от этого, можно той же рефлексией вытащить из библиотеки один заранее известный интерфейс и вызывать всевозможные функции уже через него. Это будет намного проще.
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
23.08.2016, 18:05
не туда
0
186 / 184 / 97
Регистрация: 30.04.2016
Сообщений: 478
23.08.2016, 19:56
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
Можно ли "скопировать" метод вытащенный из DLL и вставить его в мной созданный некий класс так, чтобы после одноразовой загрузки DLL, вытаскивания из неё метода, можно было забыть про DLL и больше с ней не взаимодействовать. А метод при этом уже будет методом уже моего какогото класса и чтобы его выполнить я буду обращаться к нему через экземпляр класса.
"Скопировать" метод нельзя. Можно сделать класс обертку и работать с ней.
0
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
23.08.2016, 20:30  [ТС]
"Скопировать" метод нельзя. Можно сделать класс обертку и работать с ней.
Поправте меня если не прав, но и переменные и функции по сути есть области памяти с данными. Переменные это хранилища данных и можно работать непосредственно с адресами хранилищ а можно с их содержимым. По идее с кодом функций мы вроде как работаем только как с хранилищами - указывая куда(в какую область памяти содержащую код) нужно сделать JMP. Но ведь ничем не противоречит и копирование и редактирование памяти содержащую код в процессе его выполнения. В микроконтроллерах это может и не везде но часто возможно. Просто когда мы в процессе выполнения программы обращаемся к некоторому файлу DLL мы же посути копируем код с диска в оперативку и исполняем его. И казалось бы ничего нам не мешает сделать в памяти несолько копий. И вот эти копии засунуть в некоторую "структуру" а точнее класс. И впринципе если сигнатура будет задана, то всю работу с некоторой функцией тело которой будет всунуто в саму программу уже после её запуска, мы можем адекватно реализовать в классе.
0
Эксперт .NET
 Аватар для Rius
13114 / 7675 / 1674
Регистрация: 25.05.2015
Сообщений: 23,403
Записей в блоге: 14
23.08.2016, 20:34
JustOneQuestion, да возможно, конечно. Декомпилировать нужную сборку на IL, вытащить исходники, переработать и собрать в своей программе. Только вот этот Ад ни к чему.

Здесь загружается сборка. Из неё вытаскивается объект. Ссылка на него сохраняется в классе-обёртке. Этот класс предоставляет наружу функции. При вызове этих функций, вызовы переадресовываются в класс, загруженный из сборки.
Не создавайте себе проблемы.
0
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
23.08.2016, 22:12  [ТС]
Вот рабочий код.
2 класса + Main.
Первый класс (OutSideF) читает DLL, вытаскивает методы и составляет список делегатов на эти методы.
Второй класс (OtherClass) берёт список делегатов и сохраняет у себя.
В Main создаётся экземпляр "читателя DLL", после чего экземпляр OtherClass заберает у него список делегатов. А "читатель" уничтножается. Писалось это с интересом проверить чё будет то. Можно ли методы засунусть в список делегатов и можно ли их передавать, а первоисточник уничтожить.

Оказалось можно вроде. ведь код работает, и я теперь несовсем понимаю почему. Что ж тогда такое делегат и где на самом деле хранится код тех методов что были вытащены из DLL.


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
 
 
namespace Program_Lib_Test
{
    public delegate object FDelegate(object objT, object[] ArgsT);//Делегат в трёх классах используется - объявим аж прям тут
    class Program
    {
        static void Main(string[] args)
        {
            byte[][] Params = new byte[1][] { new byte[8] };//Параметры для функций из библиотек.
 
            OutSideF TestLB = new OutSideF("Lib_Test");//Создаём экземпляр класса который занимается чтением DLL и вытаскиванием метода
            OtherClass TestDlg1 = new OtherClass(TestLB.ExeDlg);//Создаём 2 экземпляра класса, который будет брать список делегатов тех методов что мы вытащили и сохранять у себя 
            OtherClass TestDlg2 = new OtherClass(TestLB.ExeDlg);
            //TestLB.Execute(0, ref Params);
            TestLB = null; //TestDlg1 TestDlg2 уже имеют все методы что нам нужны Поэтому удаляем экземпляр который их читал из DLL
            GC.Collect();//Для верности чистим память.
            TestDlg1.Execute(0, ref Params);
            TestDlg2.Execute(1, ref Params);
            //Тут дебаг ставим и в Watch смотрим содержимое Params
            Console.ReadKey();
        }
    }
    class OutSideF
    {
        public FDelegate[] ExeDlg;
        private string LibName;
        public String[] FNames;
        public OutSideF(string LibNameT)
        {
            LibName = LibNameT;
            GetFList(LibName, ref FNames);
        }
        private void GetFList(string LibNameT, ref String[] FNamesT)
        {
            Assembly SampleAssembly;
            SampleAssembly = Assembly.Load(LibNameT);
            object[] InvokeArgs;
            MethodInfo MethTmp;
            MethodInfo GetFNamesList = SampleAssembly.GetTypes()[0].GetMethod("GetFunctionsList");//В DLL есть функция которая возвращает имена того что она содержит. Чтобы не фильтровать, а сразу знать что можно а что нельзя брать.
            InvokeArgs = new object[] { FNamesT };
            GetFNamesList.Invoke(null, InvokeArgs);
            FNamesT = (String[])InvokeArgs[0];
 
            ExeDlg = new FDelegate[FNamesT.Length];
            for (int i = 0; i < FNamesT.Length; i++)
            {
                MethTmp = SampleAssembly.GetTypes()[0].GetMethod(FNamesT[i]);
                ExeDlg[i] = MethTmp.Invoke;
            }
        }
        public bool Execute(int IndexT, ref byte[][] Params)
        {
            object[] InvokeArgs = new object[] { Params, "1" };
            bool res = (bool)ExeDlg[IndexT](null, InvokeArgs);
            return res;
        }
    }
 
    class OtherClass
    {
        private FDelegate[] ExeDlg;
        public OtherClass(FDelegate[] ExeDlgOutside)
        {
            ExeDlg = new FDelegate[ExeDlgOutside.Length];
            for (int i = 0; i < ExeDlgOutside.Length; i++)
            {
                ExeDlg[i] = ExeDlgOutside[i];
            }
        }
        public bool Execute(int IndexT, ref byte[][] Params)
        {
            object[] InvokeArgs = new object[] { Params, "1" };
            bool res = (bool)ExeDlg[IndexT](null, InvokeArgs);
            return res;
        }
    }
}
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
23.08.2016, 22:22
Цитата Сообщение от JustOneQuestion Посмотреть сообщение
я теперь несовсем понимаю почему.
Плохо что не понимаете.
Вы занулили ссылку, но перед этим вы передали эту ссылку в два объекта. Таким образом, в них эта ссылка есть (ее копия), и сам объект, на который она указывает, никуда не делся, он жив-здоров.
0
1 / 1 / 0
Регистрация: 01.05.2015
Сообщений: 84
23.08.2016, 22:41  [ТС]
Э, так а где тогда хранятся то сами методы? в том экземпляре который я пытался удалить? Казалось бы я сохранил ссылки только на методы которые MethTmp.Invoke. А что с остальными полявми и методами экземпляра класса, они тоже живы или нет? На них то вроде уже нет ссылок.
И кстати ещё один забавный момент. Если сделать ещё один ReadKey перед TestDlg1.Execute(0, ref Params);
C#
1
2
3
4
            TestDlg1.Execute(0, ref Params);
            TestDlg2.Execute(1, ref Params);
            //Тут дебаг ставим и в Watch смотрим содержимое Params
            Console.ReadKey();
и пока там будем стоять, попробовать удалить файл DLLки то будет отказано в доступе. Ээто то почему? Assembly.Load чтоли не отпускает файл, а привязывается к нему намертво? А как его отучить от такого? Или тут в другом дело?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.08.2016, 22:41
Помогаю со студенческими работами здесь

Определение функции во время исполнения программы
Добрый день! Прошу помощи. Скажите, реально ли определить функцию во время исполнения программы? Задача вообще такова: есть набор...

Создание объектов во время исполнения программы
ну от должна вона работать,а не работает,викладою.там все далжно работать,нзнаю.там описание только к кнопке,и все,больше описаний...

Оценить время исполнения программы, собственные команды
Нашел старую задачу, долго над ней думал, кое-что наработал, но не решил Реализовал почти все команды, но как сделать loop не могу...

Изменение значения Label во время исполнения программы
В поле edit ввожу строку, как реализовать подсчет длины строки в поле Label во время ввода(т.е. чтобы совместно с вводом изменялось и...

Как определить платформу во время исполнения программы?
Коллеги ! Кто знает, как во время исполнения программы на Java определить под какой операционкой она работает: Windows, Unix или Linux ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru