Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63

Использование готовой dll, явная загрузка

17.10.2022, 17:18. Показов 2996. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть dll - sqlite3, подключаю с помощью loadlibrary, получаю указатель на нужные функции, вызываю их - с этим разобрался. см. код ниже. но вот второй параметр sqlite3_open - ссылка на объект БД ее получают в примерах в интернете как sqlite3 *db но для этого используют заголовочный файл <sqlite3.h>. Но этот файл нужно как то взять из исходников sqlite3.

вопросы:
1. можно ли db handle создать без заголовочного файла только используя dll
2. если нельзя, то как лучше получить sqlite3.h

C++
1
    int sqlite3_open(const char *filename,   sqlite3 **ppDb )
C++
1
2
3
4
5
6
7
8
9
    HMODULE h;
    void (DllFunc) (char *str);
 
    h=LoadLibrary("sqlite3.dll");
 
    
    void (*pFunction)();
    (FARPROC &)pFunction = GetProcAddress(h, "sqlite3_open");
    pFunction("GRServer.sdb");
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.10.2022, 17:18
Ответы с готовыми решениями:

DLL in VC++. Создание, загрузка, использование.
Как известно, в VC++ имеется несколько типов Dll: 1.Non-MFC DLLs; 2.Regular DLLs Statically Linked to MFC; 3.Regular DLLs Dynamically...

Явная специализация шаблонной функции с использование decltype
Добрый день. Есть вопрос - в чём проблема во втором случае? Данный код компилируется: #include &lt;iostream&gt; #include...

Явная загрузка dll
Подскажите пожалуйста, что у меня в коде не так. Учился вот здесь https://www.cyberforum.ru/cpp-builder/thread154847.html но что то не...

47
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
19.10.2022, 08:48
Студворк — интернет-сервис помощи студентам
Судя по объявлению, подразумевается что-то такое:

C++
1
2
3
4
sqlite3 *adrFunc;
 
//Вызов:
  sqlite3_open("file_name", &adrFunc) ;
Ну и потом, легко же нагуглить примеры; например https://www.tutorialspoint.com... _c_cpp.htm
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
19.10.2022, 10:35
Цитата Сообщение от SergeyAK Посмотреть сообщение
в случае ОС win формируем lib - готово.
1) Если у вас MinGW, то *.lib не подойдет. нужно формаировать *.a, у MinGW библиотеки импорта в другом формате.

2) Добавлять библиотеку импорта в проект, как у вас на скриншоте показано, не надо. Добавлять надо в настройках линковщика (Build Options -> Linker Settings -> Link Libraries) в CodeBlocks.

3) Сначала вам нужно досконально разобраться как происходит компиляция в С\С++, этапы компиляции, организация файлов в проекте. Четко понимать разницу между этапами препроцессора, компиляции и линковки. Четко представлять понятие "единица трансляции". Потом будет проще с библиотеками и ошибками линковки, которые будут встречаться при их использовании.

Цитата Сообщение от SergeyAK Посмотреть сообщение
как в таком коде вызвать int sqlite3_open(const char *filename, sqlite3 **ppDb ) здесь второй параметр это тип из sqlite3.dll
Тип функции узнаете из заголовочного файла.
И вместо void (*pFunction)(); указываете его.
Например
C++
1
2
3
4
using  sqlite3_open_t = int(const char *, sqlite3 **); // тип функции  sqlite3_open
 
sqlite3_open_t* pFunction;
pFunction = (sqlite3_open_t*)GetProcAddress(h, "sqlite3_open");
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
19.10.2022, 13:06  [ТС]
Цитата Сообщение от KSergey9 Посмотреть сообщение
Ну и потом, легко же нагуглить примеры; например https://www.tutorialspoint.com... _c_cpp.htm
клевый сайт, буду знать

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
3) Сначала вам нужно досконально разобраться как происходит компиляция в С\С++, этапы компиляции, организация файлов в проекте. Четко понимать разницу между этапами препроцессора, компиляции и линковки. Четко представлять понятие "единица трансляции". Потом будет проще с библиотеками и ошибками линковки, которые будут встречаться при их использовании.
видите ли чем дело, я все это досконально уже разбирал, читал, но вот снова забыл. со временем придет понимание и ко мне.
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
19.10.2022, 14:00
Цитата Сообщение от SergeyAK Посмотреть сообщение
видите ли чем дело, я все это досконально уже разбирал, читал, но вот снова забыл.
Ну вот поэтому и проблемы. Т.е. по-хорошему, чтобы нормально эти проблемы решить, нужно весь этот материал подтянуть. Т.е. этот третий пункт - это прямой способ решить вашу проблему.
Можно начать отсюда: https://youtu.be/G_jcBrrYPAs?t=78
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
19.10.2022, 14:10  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну вот поэтому и проблемы. Т.е. по-хорошему, чтобы нормально эти проблемы решить, нужно весь этот материал подтянуть. Т.е. этот третий пункт - это прямой способ решить вашу проблему.
Можно начать отсюда: https://youtu.be/G_jcBrrYPAs?t=78
А, вот почему проблемы? :-)
ну теперь я во всеоружии.
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
20.10.2022, 12:20  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну вот поэтому и проблемы. Т.е. по-хорошему, чтобы нормально эти проблемы решить, нужно весь этот материал подтянуть. Т.е. этот третий пункт - это прямой способ решить вашу проблему.
Можно начать отсюда: https://youtu.be/G_jcBrrYPAs?t=78
Эх, начал я смотреть рекомендуемое видео, интересно конечно но на минуте 15-ой я уже "поплыл". Слишком оно профессиональное, а я же начинающий в этой среде.

и по поводу отсутствия необходимости .lib к windows dll я тоже засомневался. вы ранее сообщили, что если у меня codeBlock то .lib не нужно а нужно .a
https://www3.sqlite.org/howtocompile.html четко сказано как выполнить компиляцию из исходников для win, мало того у меня же получился рабочий пример в среде CodeBlock с использованием dll и lib. поищу теперь "библиотеки импорта для MinGW" для интереса
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
20.10.2022, 12:25
Цитата Сообщение от SergeyAK Посмотреть сообщение
https://www3.sqlite.org/howtocompile.html четко сказано как выполнить компиляцию из исходников для win,
Так это про сборку самого sqlite
А вы ж про подключение готовой (собранной) dll спрашиваете

Сами намешали всё в кучу, не надо.

Цитата Сообщение от SergeyAK Посмотреть сообщение
в среде CodeBlock с использованием dll и lib
Разбираться с каким-то CodeBlock желающие не факт что найдутся, но вполне может быть, что они и lib формат поддерживают.
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
20.10.2022, 12:45
Цитата Сообщение от SergeyAK Посмотреть сообщение
но на минуте 15-ой я уже "поплыл"
Никто не обещал, что будет легко. Пишите конспекты.
По сути необходимая для вашего случая информация содержится как раз в первых 15-25 минутах. Дальше пока можно не смотреть.

Цитата Сообщение от SergeyAK Посмотреть сообщение
мало того у меня же получился рабочий пример в среде CodeBlock с использованием dll и lib
Нет, не получился.
Если речь про пост #16, то там у вас сборка примера с использование файла sqlite3.c, который вы добавили в проект. Никакие библиотеки, ни lib, ни a при таком варианте не нужны. В любом случае lib-файл у вас там был добавлен неправильно, но это никак не повлияло на результат по причине использования непосредственно sqlite3.c.

Цитата Сообщение от SergeyAK Посмотреть сообщение
https://www3.sqlite.org/howtocompile.html четко сказано как выполнить компиляцию из исходников для win
Если речь про пункт 5, то там описана только сборка DLL. Сборка библиотеки импорта к ней не описана.
Если взять за основу командную строку, которая дана по ссылке, то сборка DLL и одновременное получение библиотеки импорта к ней будет выглядеть так:
Bash
1
gcc -shared sqlite3.c -Wl,--out-implib,libsqlite3.a -o sqlite3.dll
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
20.10.2022, 14:19  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет, не получился.
Если речь про пост #16, то там у вас сборка примера с использование файла sqlite3.c, который вы добавили в проект. Никакие библиотеки, ни lib, ни a при таком варианте не нужны. В любом случае lib-файл у вас там был добавлен неправильно, но это никак не повлияло на результат по причине использования непосредственно sqlite3.c.
да, и в посте 16 я указал что "...но я удалил из проекта sqlite3.dll ведь вместо него sqlite3.c теперь в проекте. тогда получается что я подключил библиотеку неявно..."

с этим я разобрался. я описал, что хотел использовать dll а в итоге использовал исходники. я пока не понимаю преимущества использования исходников или библиотеки dll. но для себя я задал задачу использовать именно dll, так как я обычно делаю это в своей сфере в другой среде. и тут с подключением dll возникли вопросы. я конечно искал информацию в интернете и на официальных сайтах sqlite интересная статью прочел здесь https://www.rsdn.org/article/com/introcom.xml#EKD , но до конца не все понял, поэтому обратился на форум, тут есть и хорошие советы, но есть и не очень.

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Если речь про пункт 5, то там описана только сборка DLL. Сборка библиотеки импорта к ней не описана.
Если взять за основу командную строку, которая дана по ссылке, то сборка DLL и одновременное получение библиотеки импорта к ней будет выглядеть так:
да , сборку библиотеки там я не нашел и больше нигде не нашел. так что воспользуюсь вашей рекомендацией.
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
20.10.2022, 14:24
Цитата Сообщение от SergeyAK Посмотреть сообщение
я задал задачу использовать именно dll
DLL, как уже выше говорилось, можно использовать применяя связывание при сборке программы - через библиотеку импорта, либо применяя динамическую загрузку.
Динамическая загрузка хороша, например, для организации plugins, а вот такие объемные по интерфейсу библиотеки как sqlite лучше связывать во время сборки (иначе замучаетесь описывать загруженные функции, а реальной пользы от этого около нуля).
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
20.10.2022, 16:31  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
DLL, как уже выше говорилось, можно использовать применяя связывание при сборке программы - через библиотеку импорта, либо применяя динамическую загрузку.
Динамическая загрузка хороша, например, для организации plugins, а вот такие объемные по интерфейсу библиотеки как sqlite лучше связывать во время сборки (иначе замучаетесь описывать загруженные функции, а реальной пользы от этого около нуля).
ну польза у меня тут ознакомительная, тем более за скоростью не спешу, интересны оба варианта.
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
20.10.2022, 16:47
Цитата Сообщение от SergeyAK Посмотреть сообщение
интересны оба варианта.
В посте #22 показал как обращаться с динамической загрузкой.
Таким образом нужно будет протащить каждую функцию (из нужных естественно).

Добавлено через 4 минуты
По поводу линковки библиотеки:
Там же в пункте 2) указал куда прописывать библиотеку в CodeBlocks, а в посте #28 как ее собрать.
Прописываете без префикса lib и расширения.
Т.е. если библиотека импорта называется libsqlite3.a, то вписать в окошко надо sqlite3.
Путь к ней тоже указываете в соседней вкладке Search Directories -> Linker.
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
21.10.2022, 03:14  [ТС]
С учетом всего вышеописанного оба варианта получились, пока вызов sqlite3_open, но остальное(вызов прочих процедур) уже ясно.

Цитата Сообщение от KSergey9 Посмотреть сообщение
Разбираться с каким-то CodeBlock желающие не факт что найдутся, но вполне может быть, что они и lib формат поддерживают
а чем пользуетесь кроме MS Visual Studio и Qt так сказать полно коммерческих тяжелых продуктов?
eclipse c++ у меня тоже не взлетело слишком сложно без понимания.

codeBlocks я настроил сам, собственно нужно было прочитать что существует компилятор( сборщик, линковщик и т.д. сейчас мне за терминологию спросят ) minGW для win , указать путь в настройках программы к нему, ну еще добавил в переменную PATH, поскольку без этого программы работали только в среде разработки, отдельно консольное приложение не собиралось.
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
23.10.2022, 03:51  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
using  sqlite3_open_t = int(const char *, sqlite3 **); // тип функции  sqlite3_open
sqlite3_open_t* pFunction;
pFunction = (sqlite3_open_t*)GetProcAddress(h, "sqlite3_open");
как я уже сказал , пример ваш работает отлично.
полдня читал про using , несколько способов применения(объявление, директива) вот не нашел или не понял про данный пример. так то понимаю, что тут идет обозначение типа значения возвращаемого функцией sqlite3_open и дальше идет даже приведения типа (sqlite3_open*) , но что это за формат записи
C++
1
using  sqlite3_open_t = int(const char *, sqlite3 **); // тип функции  sqlite3_open
расскажите название варианта использования using ведь тут я вижу int - возвращаемый тип sqilite3_open, далее перечисление ее параметров с их типами const char *, sqlite3 **, но нет названия самой функции, как происходит это присваивание, названием функции можно пренебречь?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13215 / 6847 / 1826
Регистрация: 18.10.2014
Сообщений: 17,343
23.10.2022, 04:19
Цитата Сообщение от SergeyAK Посмотреть сообщение
ведь тут я вижу int - возвращаемый тип sqilite3_open, далее перечисление ее параметров с их типами const char *, sqlite3 **, но нет названия самой функции
Это тип функции. Он никак не привязан ни к какой конкретной функции. В нем нет и не может быть никакого "названия функции". Как нет названий параметров.

Например, функция int foo(char *name, double value) имеет тип int (char *, double). Функция int bar(char *file, double resolution) имеет тот же самый тип.

Цитата Сообщение от SergeyAK Посмотреть сообщение
как происходит это присваивание
Здесь нет никакого "присваивания". Символ = лишь косметический синтаксический элемент в таком объявлении. Оно говорит, что имя sqlite3_open_t будет синонимом для типа int(const char *, sqlite3 **).
1
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
23.10.2022, 12:01  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это тип функции. Он никак не привязан ни к какой конкретной функции. В нем нет и не может быть никакого "названия функции". Как нет названий параметров.

Например, функция int foo(char *name, double value) имеет тип int (char *, double). Функция int bar(char *file, double resolution) имеет тот же самый тип.



Здесь нет никакого "присваивания". Символ = лишь косметический синтаксический элемент в таком объявлении. Оно говорит, что имя sqlite3_open_t будет синонимом для типа int(const char *, sqlite3 **).
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
26.10.2022, 14:11  [ТС]
все получается. но как я понял при такой варианте подключения библиотеки нужно описывать вызов каждой функции.
я описал функцию открытия бд, функцию выбора записей а перебор результата - не описывал.
ошибок компиляции нет, результат вышел без ошибок. хм. почему?


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
int main()
{
    HMODULE h; //дескриптор функции по типу winAPI
    h=LoadLibrary("sqlite3.dll"); // libsqlite3.a - библиотека
    int rc;
    const char *dbName= "GRServer.sdb";
   
    if (h==NULL)
    {
        cout << "sqlite3.dll not found or there is a download error \n";
        return 0;
    }
 
    sqlite3 *db;
    using  sqlite3_open_t = int(const char *, sqlite3 **); // тип функции  sqlite3_open
 
    sqlite3_open_t* pFunctionOpen; //объявляем указатель pFunction
    pFunctionOpen = (sqlite3_open_t*)GetProcAddress(h, "sqlite3_open");//присваеваем значение указателю, одновременно приводя возвращаемое значение к нужному типу
    //приведение типов важно https://learn.microsoft.com/ru-ru/cpp/build/getprocaddress?view=msvc-170&viewFallbackFrom=vs-2019
    rc=pFunctionOpen(dbName, &db);
 
    if (db==NULL)
    {
        cout << "is unable to allocate memory to hold the sqlite3 object \n";
        return 0;
    }
    else
    {
        if(rc==SQLITE_OK)
        {
            cout << "the database " << dbName << " has been opened(created) successfully!\n";
        }
        else
        {
           cout << "an error occurred when opening the database " << dbName << " error_code: " << rc << endl;
           return 0;
        }
    }
 
    //using std::cout;
    using sqlite3_prepare_t = int(sqlite3*, const char*, int, sqlite3_stmt**, const char**);
    sqlite3_stmt *result;
 
    sqlite3_prepare_t* pFuncSelect;
    pFuncSelect = (sqlite3_prepare_t*)GetProcAddress(h, "sqlite3_prepare");
 
    rc=pFuncSelect(db, "select * from 'Order' where id = '00001389400000012245'", -1, &result, NULL);
    if (rc != SQLITE_OK)
    {
        cout << "function execution error sqlite3_prepare\n";
        //fprintf(stderr, "Error en la consulta: %s.\n", sqlite3_errmsg(db));
        //sqlite3_close(db);
        return 0;
    }
    else
    {   int i=0;
        while ( sqlite3_step(result) == SQLITE_ROW)
            {
                i++;
            }
 
 
        cout << i << " lines were output\n";
 
    }

the database GRServer.sdb has been opened(created) successfully!
8 lines were output

Process returned 0 (0x0) execution time : 0.031 s
Press any key to continue.

Добавлено через 2 минуты
Цитата Сообщение от SergeyAK Посмотреть сообщение
sqlite3_step
эта функция не описана в моем коде через getProcAddress
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,831
26.10.2022, 14:42
Цитата Сообщение от SergeyAK Посмотреть сообщение
эта функция не описана в моем коде через getProcAddress
Потому что либо библиотека еще подключена на этапе линковки в проект, либо исходник sqlite добавлен в проект.
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
26.10.2022, 14:53  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что либо библиотека еще подключена на этапе линковки в проект, либо исходник sqlite добавлен в проект.
нет, исходника нет. здесь рассматриваю вариант работы через LoadLibrary.

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Таким образом нужно будет протащить каждую функцию (из нужных естественно).
я так понял что каждую. в итоге я протащил sqlite3_open, sqlite3_prepare
а sqlite3_step- нет
0
2 / 1 / 0
Регистрация: 04.11.2021
Сообщений: 63
26.10.2022, 15:04  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что либо библиотека еще подключена на этапе линковки в проект


да подключена в проект, а когда была не подключена , то LoadLibrary("sqlite3.dll") было недостаточно для работы , вызываемые функции не находились, поэтому была dll подключена в проект.
так ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.10.2022, 15:04

Явная загрузка .dll
Поблема: библиотеку подключил, но внутри никак не найду функцию HMODULE hLibrary = 0; hLibrary = LoadLibrary(&quot;MyDll.dll&quot;); ...

Явная загрузка DLL
Господа начал изучать , первая программа и проблема , буду признателен за помощь . вот кот dll #include &quot;dll.h&quot; #include...

явная загрузка dll
#include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;windows.h&gt; #include &lt;tchar.h&gt; HMODULE p_dll = LoadLibrary(L&quot;create_dll.dll&quot;); ...

Явная загрузка DLL
Доброго дня всем! Мне надо сделать явную подгрузку dll в проекте и использовать с нее некую функцию (например FormMatrix() ). Эта...

Явная загрузка DLL из ДРУГОЙ DLL
Помогите явно загрузить DLL из исходной DLL Исходная DLL Unit1.h HINSTANCE dllInstance2; typedef int(__import *FType(int)); ...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru