Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт фев 21, 2020 12:41

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 82 ]  На страницу 1, 2, 3, 4, 5, 6  След.
Автор Сообщение
 Заголовок сообщения: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Вс янв 09, 2011 21:37 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Автор: MGW
Дата публикации: 09.01.11
оригинал статьи взят http://mgw.narod.ru/doc.htm

Подключение графической библиотеки QT к SPF 4.20

Введение. Зачем это нужно.
Форт интересный, необычный язык, однако его консольный вариант не выглядит современным решением. Необходим графический нтерфейс, причём работающий и в Windows и в Linux. К тому же, желательно иметь возможность использовать различные, готовые механизмы, как то сетевые интерфейсы, XML, OpenGL и т.д. Все перечисленные возможности, реализованные в кросплатформенном варианте, а так же различные универсальные алгоритмы содержит библиотека QT.
Именно её подключением к форту мы и будем заниматься. Данный пример работы с С++ библиотекой, которой является QT, можно рассматривать как вариант общего подхода для работы с динамическими библиотеками C++ содержащими в разнообразных DLL и SO.
В качестве форта будем использовать SPF-4.20. Он доступен для Windows и Linux, имеет открытые исходные тексты, активно поддерживается русскоязычным сообществом. Содержит большое количество отлаженных кросплатформенных библиотек.

Постановка задачи. Необходимость во внешней DLL и вызовах с SPF методов С++.
Итак, наша цель научиться использовать из SPF возможности QT. Хотя теоритически можно использовать С++ библиотеки непосредственно из форта, моделируя работу С++ (пример с.f), но практически это очень сложно. Главные трудности, как мне кажется, это трудность с подсчетом размера памяти для создаваемого объекта, а так же трудность в создании и перекрытии виртуальных функций в С++ средствами форта. В связи с этим нам придется использовать собственную динамическую библиотеку FQT. Естественно, что для Windows это будет FQT.DLL а для Linux fqt.so Писать её будем на С++.
Я использовал MSVC-6.0 для Windows и gcc для Linux, и соответственно на их синтаксис я буду ориентироваться в примерах. С другой стороны полностью переписать (обернуть в собственные вызовы) QT практически невозможно ввиду её размера. По этому, я использовал смешанный подход. Динамическая библиотека FQT (которую мы напишем) используется для создания объектов, перекрытия виртуальных методов, вызова обработчиков событий. Однако с форта, мы будем напрямую вызывать методы объектов QT, прямо по их адресам в DLL-ках. Такой подход позволяет минимизировать объём работ в С++, при создании FQT, и к тому же добавлять методы можно прямо из форта, не прибегая к С++.

Различные типы вызовов: CDECL, WINAPI, THIS-Call.
Для возможности вызова функций из динамических библиотек, нам необходимо иметь возможность организовывать различные типы вызовов непосредственно из SPF. Сам вызов, это CALL (в терминах ассемблера), а типы вызовов, это способ передачи параметров, через стек, регистры, их порядок и т.д.
    stdcall/winapi - широко используется в Windows
    cdecl-call - С++ стандарт
    this-call - для работы с объектами С++.
Вызовы типа this-call содержат неявный указатель на данные объекта, передаваемый в вызовах данного типа. Проблема в том, что различные компиляторы по разному организуют данные типы вызовов. Как я говорил выше, мы будем ориентироваться на MSVC 6.0 и gcc. Таким образом нам нужны вызовы:
    CDECL-Call - Стандарт для C++
    STDCALL-Call - Работа с WinAPI
    WINAPI-Call - Работа с WinAPI
    Extern - Работа с глобальными переменными
    THIS-CDECL-Win-VC-Call - Работа с объектами в MS VisualC 6.0 (windows)
    THIS-CDECL-Linux-gcc-Call - Работа с объектами в gcc (linux)
Для организации вызовов типа CDECL-Call, STDCALL-Call, WINAPI-Call – воспользуемся словами PAS-EXEC и C-EXEC из библиотеки SPF ~ac\lib\ns\so-xt.f Для организации вызова THIS-CDECL-Win-VC-Call воспользуемся словом THIS-CDECL-CALL-ECX написанном на встроенном ассемблере. Алгоритм этого вызова такой же, как и у CDECL-Call, но указатель на объект передаётся в регистре ECX. Для THIS-CDECL-Linux-gcc-Call тоже что и CDECL-Call, но указатель на объект первый в списке аргументов.
Более подробно о вызовах http://www.programmersheaven.com/2/Calling-conventions
Так же следует помнить, что в динамических библиотеках C++ используется искажение имен функций, и метод QWidget::show() будет назван ?show@QWidget@@QAEXXZ или что то похожее.

Модуль загрузки библиотек. Двойственность загрузки библиотеки.
Теперь, когда понятно, как использовать вызовы, нужно знать самое главное, а именно адрес на который передать управление. Файлы DLL (Windows) и SO (Linux) как раз и содержат готовые к применению функции, которые мы и будем вызывать. Обычно, при работе на С++ или других языках программирования, компилятор берет на себя всю работу, по поиску, загрузке и вызову нужных функций. Мы же в SPF всё это будем делать сами.
Программа явно может загружать и выгружать динамические библиотеки. Делает она это при помощи функций API:
    Для Windows: LoadLibrary("Имя библиотеки"...)
    Для Linux: dlopen("Имя библиотеки"...)
Когда библиотека загружена в память, следующим этапом надо найти адреса нужных функций. Динамическая библиотека содержит таблицу имен функций. Есть много утилит которые показывают эту таблицу. Для Linux : objdump -t имя.so например. Адрес функции, это адрес куда надо передать выполнение для выполнения функции. Ищем этот адрес:
    Для Windows: GetProcAddress("Имя функции"...)
    Для Linux: dlsym("Имя функции"...)
Если вызов прошел удачно, то на выходе будет адрес нужной нам функции. По этому адресу можно её вызвать. Перед вызовом нужно положить в стек параметры, а после вызова забрать результат выполнения, если он есть.
При работе в форте, надо учитывать факт того, что программа форта работает как бы в двух режимах. Первый, непосредственно интерпретация программы на форте, а второй – это работа исполняемого модуля (EXE) после компиляции программы. Так вот загрузка динамических библиотек должна учитывать такую двойственность. Я долго не мог понять, почему запуск spf4 Имя.f работает правильно, а EXE модуль Имя.EXE валится по ошибке.
Другими словами, загрузку библиотеки надо осуществлять непосредственно в момент работы готовой программы, перед использованием ей вызова внешних функций.

Для обеспечения условия правильной загрузки, а так же для упрощения читабельности кода на форте и для обеспечения гибкости вызовов применяется несколько слов на форте (Library”, _-Call" и т.д.), реализующих следующий алгоритм (пример):
    Library" libc.so.6" libc – декларация имени загружаемой библиотеки. Создаётся новое определяющее слово libc. Создаётся пустой список с именами функций. Ни какой загрузки библиотеки в данный момент нет.
    Library@ libc Nкол_аргументов ТИП_ВЫЗОВА” fopen” fopen – добавляется элемент в список, содержащий имя функции, тип вызова и количество параметров. Ни какой загрузки библиотеки в данный момент нет.
    LibraryLoad libc – именно в этот момент происходит реальная загрузка динамической библиотеки. Далее перебирая список, созданный на предыдущем этапе, осуществляется поиск и сохранение адресов функций. Таким образом слово fopen (см. пред. описание) запомнит адрес для вызова, количество аргументов и тип вызова.
Обращаю особое внимание, при создании файлов EXE, обязательно перед реальным использованием в EXE вызовов функций из динамической библиотеки, необходимо осуществлять загрузку её в память: LibraryLoad libc (в качестве примера).

Объекты в SPF и обоснование их применимости для данной задачи.
Имея подключенные внешние функции, можно писать любые программы. Но, пользоваться прямо такими вызовами не удобно, громоздко. Воспользуемся библиотекой ~day\hype3\hype3.f для организации объектно-ориентированного (ОО) механизма. Мы должны для каждого созданного объекта QT (C++) запомнить его адрес непосредственно в объекте SPF, что бы потом передавать его в качестве аргумента внешним функциям. Все объекты у нас описываются похожим образом. Рассмотрим типичное описание на примере QWidget:
Код:
// Базовый класс QWidget, на него замыкаются другие виджеты
CLASS fQWidget
   1 CELLS PROPERTY adr_fQWidget   // Запомним адрес объекта QWidget
: create     // Инициализация класса
   0 СоздатьОкно      // Создать объект QWidget в С++ и его адрес на стек
     adr_fQWidget !   // Запомнить адрес QWidget
   ;
: show  // Показать окно
   adr_fQWidget @ ПокажиОкно DROP  // вызов внеш. функции и сброс кода возврата
   ;
   
// Здесь СоздатьОкно – это вызов внешний функции типа CDECL-Call с 1 параметром:
Library" fqt.dll" libfqt          // Грузанем нашу библиотеку в память
Library@ libfqt  1 CDECL-Call" QT_QWidget" СоздатьОкно

// Здесь ПокажиОкно – это вызов внешней функции QWidget.show().
Library" QtGuid4.dll" QtGui       // Грузанем библиотеку Qt в память
Library@ QtGui  0 THIS-CDECL-Win-VC-Call" ?show@QWidget@@QAEXXZ" ПокажиОкно // ПокажиОкно

Таким образом, вызовы QT мы включаем в нашу объектную иерархию. Так как в QT объекты связаны наследованием, мы тоже будем наследовать объекты. Это сделано для того, что бы можно было использовать методы QWidget (базовый класс) для других клссов, например QTextEdit. Все визуальные классы наследуют метод show, определенный в классе QWidget. Конечно повторить всю QT мы не можем, но в состоянии довольно быстро добавлять нужные методы и классы по мере необходимости.

Архитектура нашей программы.
Код:
+----------------------+              +---------------------------------+
|Наша программа на SPF |----явно----->| fqt.dll (наша всп. библ. на C++ |
+----------------------+              +---------------------------------+
     |                                                     |
     |            +---------------------------------+      |
     +---явно---->| QtGui.dll, QtCore.dll и т.д.    | <----+ неявно через С++
                  +---------------------------------+

Наша программа на SPF взаимодействует с fqt.dll для тех действий, которые тяжело повторить на форте и взаимодействует прямо с QT (QtCore.DLL, QtGui.DLL) для подключения методов (см описание QWidget выше). Обратите внимание, на искажение имён (?show@QWidget@@QAEXXZ) вносимое компилятором С++. В этом имени зашифрован тип вызова и кол параметров. Для разных компиляторов может быть различным. Почему я решил использовать именно такую архитектуру? По тому, что без spf.dll не обойтись, нужно перекрывать виртуальные функции C++ и обрабатывать события, а с другой стороны всю QT запихать в spf.dll нет возможности. К тому же описать в SPF новый метод очень просто и для этого не нужно менять fqt.dll. Это позволяет свести к минимуму работу с C++.

Основное приложение QT. Главная процедура. Ревызов из DLL.
Вот мы и подошли к очень важному, принципиальному моменту. Правильная последовательность вызовов. Честно сказать, я почти полгода не мог найти правильную последовательность вызовов QT. А всё потому, что думал на C++, а не на ассемблере :cry: . Для того, что бы понять суть, рассмотрим работу с QT из С++.
Типичная (минимальная) программа:
Код:
#include        // Включить в программу файлы заголовков

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);     // Инициализация Qt
   ..... работа с графикой ........
    return app.exec();                // Цикл опроса графических событий
}

Как видно, есть всего две функции (QApplication и app.exec), которые как скобки обрамляют основное тело программы. В начале я пытался просто вызвать эти две функции из SPF (смотри http://mgw.narod.ru/algoritms.htm#SPF-QT, и даже что то работало. Однако программа валилась при любой возможности. После исследования работы под отладчиком MSVC 6.0 данного варианта, я понял, что проблема в наборе значений регистров в процедуре main(). Совершенно точно надо было обеспечить сохранность и неизменность регистров EBP и некоторых других между вызовами QApplication и app.exec(). Так как из SPF это сделать проблематично, я подумал, а почему бы не передать вызов непосредственно в main(), а уже из неё вызвать форт. Таким образом алгоритм взаимодействия SPF и QT следующий:
Код:
(SPF)                                                  (C++) fqt.DLL
=============                                        =================
: адрSPF  // CALLBACK <-------+             
    Создать QWidget ----------|---------->  СоздатьQWidget()
    Создать ......            |             {
;                             |                return NEW QWidget();
                              |             }
                              |             
: mainSPF                     |
    адрSPF argv argc          |                               
    ИнициализацияQT ----------|---------->  ИнициализацияQT(argc,argv,адрSPF)
;                             |             {
                              |               app=QApplication app(argc,argv);
                              ----------------Вызов адрSPF
                                              return app.exec()
                                            } 

Таким образом, ИнициализацияQT в fqt.dll выступает как функция main(), из которой вызываются различные процедуры (SPF). Так как С++ за нас сохраняет всё что ему нужно между вызовами QApplication и app.exec(), то всё сразу стало нормально работать. Приведенное выше взаимодействие с QT работает нормально не только в SPF но и других языках программирования. Следует отметить, что для SPF пришлось модернизировать работу ИнициализацияQT(argc,argv,адрSPF). Прямой вызов не работал и заработал только когда я вставил сохранение регистров.
Код:
ИнициализацияQT(argc,argv,адрSPF)
{
     app=QApplication app(argc,argv);
     _asm{
         PUSH EBP
         PUSH EAX
         }
     Вызов адрSPF
     _asm{
         POP EAX
         POP EBP
         }
     return app.exec()


Данная последовательность позволяет нам сохранить состояние нужных регистров перед вызовом CALLBACK и востановить их после вызова.

CALLBACK и их параметры. Виртуальные методы в объектах С++.
К этому моменту, мы разобрали почти все принципиальные моменты построения связки между SPF и QT. Однако есть ещё одна проблема. Объекты QT используют большое количество виртуальных методов. Программируя на С++ мы должны перекрыть их, что бы обеспечить их функциональность в рамках нашей задачи. Вопрос, как это сделать с форта? Я не знаю. По этому, я просто в fqt.DLL сам перекрываю эти виртуальные методы, заставляя их вызвать функцию (слово) SPF. Адрес для вызова сохраняется в переменных (полях данных или свойствах) конкретного объекта. Посмотрим это на примере организации объекта QWidget.
Пример. Нам надо организовать объект QWidget с дополнительным свойством вызова функции на событие изменение размера самого окна. Почитав документацию к QT видим, что существует виртуальный метод void QWidget::resizeEvent(QResizeEvent *), который будет вызван при изменении размера окна. Т.к. как с SPF перекрыть такой метод я не знаю, то приходится вводить следующую конструкцию в fqt.DLL
Код:
class zQWidget : public QWidget
{
    Q_OBJECT
public:
    zQWidget( QWidget* parent = 0 );
    ~zQWidget();

    void *aOnResize;    // Сохраняет адрес слова CALLBACK форта
    void resizeEvent( QResizeEvent * ); // наш обработчик события
};

void zQWidget::resizeEvent( QResizeEvent *a ) // Тело нашего обработчика
{
      // если сохр адрес не нулевой, то вызови функцию в SPF
   if (aOnResize!= NULL) ((ExecZIM_1_0)aOnResize)((void *)a);
}
// !!! Установить обработчик на resizeEvent
extern "C" FQT_API void QT_QWidget_onresize(zQWidget* qw, void *uk) {
   qw->aOnResize = uk;
}

Таким образом мы ввели в fqt.DLL возможность обработать событие «изменение размера окна». Для правильной обработки этого события из SPF нам надо:
    1 - Создать в SPF CALLBACK который будет обрабатывать данное событие
    2 - Установить (активизировать) обработчик, записав адрес обработчика в поле объекта. Для этого используется внешняя функция QT_QWidget_onresize. Соответственно, если мы запишем 0 в адрес обработчика, то отключим обработку события. По умолчанию, обработка событий отключена.

Отладка DLL и SPF. Работа с отладочными словами. INT3.
Важная проблема, при разработке такого комплекса, это отладка. Для примера расскажу, как я вёл отладку в MSVC 6.0. Текст библиотеки fqt.DLL написан на С++. Значит нам надо просто вызвать данную библиотеку на выполнение, а с SPF вызывать нужные функции. Отладка DLL на С++ описана подробно в Интернете. Нам надо просто во вкладках проекта установить, что основная программа будет SPF с параметрами (spf4 console.f). При запуске на выполнение из IDE MSVC будет сообщение, что SPF не имеет отладочной информации, но нам это не принципиально. Главное, если мы поставим точку остановки на текст DLL – отладчик включится при достижении этого места. Таким образом мы можем контролировать приходящие из SPF параметры и вести отладку нашей fqt.DLL.
Кстати, ни чего не мешает нам вести отладку ассемблерных слов в SPF, используя для этого MSVC (или любой другой отладчик). Что такое «точка останова» в терминах ассемблера? Это просто машинная команда INT 3, встретив которую управление передаётся отладчику. Просто в SPF определяем слово:
Код:
CODE BreakPoint           // Прерывание для внешнего отладчика
    INT 3
    RET
END-CODE

Теперь встретив это слово, произойдет прерывание и переход в отладчик, где можно спокойно дизассемблировать код, посмотреть память или состояние регистров, выполнить программу по шагам и т.д. и т.п. В Linux похожим образом я использовал отладчик gdb и ddd.

Основной шаблон графической программы.
Теперь, когда мы разобрали основные части нашей библиотеки, поговорим о минимальной программе с использованием графики QT. Но прежде пару слов о подключении DLL или SO. Для Windows всё просто, поместите fqt.DLL в каталог с самой программой (сохраненной по SAVE) или в каталог SPF. Поиск DLL в Windows начинается с каталога программы. А вот в Linux это не так. Там поиск библиотеки происходит по строго определенному маршруту. Для включения в этот маршрут каталога программы я использую переменную окружения:
LD_LIBRARY_PATH=`pwd`; export LD_LIBRARY_PATH
Запуск данной конструкции присваивает переменной LD_LIBRARY_PATH текущий каталог и делает её видимой другим программам. Таким образом, текущий каталог становится доступным для поиска fqt.so которая содержит связку с QT Linux.

Итак минимальная программа должна включать:
    Подключить определения
    1 – Ассемблерных вызовов THIS-CDECL-CALL-ECX, THIS-CDECL-CALL и т.д.
    2 – Подключить вызовы PAS-EXEC и C-EXEC (из ~ac\lib\ns\so-xt.f)
    3 – Подключить работу с DLL и SO: Library” –Call” CDECL-Call" и т.д.
    4 – Декларируем загрузку FQT.DLL (FQT.SO)
    5 – Декларируем точки вызова нужных функций и методов QT
    6 – Определяем классы для работы с QT используя ~day\hype3\hype3.f
    Создать объекты
    7 – Создаём объекты используя NEW
    Создать CALLBACKи
    8 – Создаём CALLBACK для обработки вызова из стартовой функции FQT.DLL
    9 – Создаём CALLBACKи для обработки виртуальных вызовов, если они нужны
    Программируем логику
    10 – Определяем слово main (стартовое) где:
    Грузим декларированные библиотеки LibraryLoad libfqt
    Вызываем стартувую функцию в FQT: aonForth @ ARGV ARGC СоздатьПриложение // Инициализация QT
    Действия по выходу из графики. SAVE программы.
Получилось не мало, но и задача сложна. К тому же большинство действий можно описать только один раз, а потом подключать в файле. Я стараюсь писать подробно, что бы вы поняли суть подхода. Ни чего не мешает подключить это всё к любому другому форту или вообще к другому языку программирования. Да и всё равно, это намного короче, чем программировать на Win API, а для Linux вообще реальной альтернативы нет.
Главное, на выходе реальный кросплатформенный текст на SPF одинаково работающий и в Windows и в Linux!

Графическая консоль, как пример работы с библиотекой.
В качестве примера посмотрим на текст графической консоли console.f Для успешной работы с QT надо представлять, как взаимодействуют объекты внутри неё. Так как FQT.DLL всего лишь обертка, она не скрывает внутренности QT. Одним словом, надо понимать, что такое Widget, layout и т.д.
Графическая консоль представляет собой окно типа QMainWindow, в которое вставлен главный выравниватель QLayout, в который в свою очередь вставлены редактор QTextEdit и строка ввода QLineEdit. Так же в QMainWindow вставлена статусная строка QStatusBar. Для строки ввода QLineEdit определён CALLBACK для события нажатия на Enter. Его задача, прочитать строку из строки ввода, скопировать её в окно редактора и выполнить через EVALUATE. Следует обратить внимание на тот факт, что все объекты QT работают со строками типа QString. По этому везде ведется преобразование между обычными строками SPF и QString.
Код:
Пример слово
: TYPE_W   // ( As Nstr -- ) Вывести строку SPF в окно QTextEdit
   drop qs1 set       // qs1 объект QString запоминает строку методом set
   qs1 @ te1 append   // te1:QTextEdit забирает qs1:QString и вставляет append
   ;

Так же в тексте программы console.f определены слова для отладки. Это модальный диалог и окно распечатки стека. Они останавливают ход программы и позволяют посмотреть значения на стеке, распечатать дамп памяти или просмотреть значение переменных.

Заключение.
Я этой короткой статье я попытался описать способ подключения графической библиотеки QT к SPF. Остались неосвещенными множество моментов, как то динамическое создание объектов, конструкторы и деструкторы и т.д. и т.п. Надеюсь, что это еще всё впереди.

Выражаю огромную благодарность участникам данного форума, за исчерпывающие советы и идеи высказанные при создании этого ПО.

Исходные тексты и пример (console.f) для Windows http://mgw.narod.ru/spfqt_win.zip

Исходные тексты и пример (console.f) для Linux http://mgw.narod.ru/spfqt_linux.zip


Последний раз редактировалось mgw Вс янв 09, 2011 23:25, всего редактировалось 1 раз.


За это сообщение автора mgw поблагодарил: mOleg
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Вс янв 09, 2011 23:17 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Ср дек 06, 2006 09:23
Сообщения: 648
Благодарил (а): 6 раз.
Поблагодарили: 25 раз.
мощно...... :shock:


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 11:52 
Не в сети

Зарегистрирован: Ср июл 05, 2006 14:44
Сообщения: 232
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
спасибо автору за упорный труд по прорубанию форточки в мир Qt


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 14:38 
Не в сети

Зарегистрирован: Ср май 10, 2006 13:51
Сообщения: 202
Благодарил (а): 3 раз.
Поблагодарили: 4 раз.
Linux, ошибка:
Код:
Exception #2 at: console.f:414:31:
  S" lib/ext/help_w.f  INCLUDED
                             ^ -2003 Слово или файл не найдены

lib/ext/help.f вроде катит.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 15:06 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4999
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 20 раз.
Поблагодарили: 58 раз.
mgw писал(а):
При работе в форте, надо учитывать факт того, что программа форта работает как бы в двух режимах. Первый, непосредственно интерпретация программы на форте, а второй – это работа исполняемого модуля (EXE) после компиляции программы. Так вот загрузка динамических библиотек должна учитывать такую двойственность. Я долго не мог понять, почему запуск spf4 Имя.f работает правильно, а EXE модуль Имя.EXE валится по ошибке.

тут есть непонятый автором момент. В СПФ (по крайней мере под WIN) есть специальный список инициализируемых библиотек (см. WINAPLINK), в этот самый список связываются все используемые функции АПИ, и во время первого использования (если не ошибаюсь) происходит связывание. То есть, если все сделать правильно, то разницы не будет никакой.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 16:59 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
oco писал(а):
Linux, ошибка:Код:Exception #2 at: console.f:414:31:  S" lib/ext/help_w.f  INCLUDED                             ^ -2003 Слово или файл не найденыlib/ext/help.f вроде катит.


Здесь очередная моя недоделка. В SPF Linux я пользуюсь help, но переделанной (help_w.f).
В fqt.so.2.0 (да и в fqt.dll) есть глобальная переменная NameCodec. Она указывает на буфер в fqt,
который содержит имя кодовой таблицы, с которой работает QT. Это обычная строка C типа.
Содержит имя кодовой таблицы, из которой идет перекодировка в QString.
Для Linux: UTF-8
Windows: Windows-1251
DOS: IBM 866
и т.д. Их там очень много. Подробнее в документации QT.

Я просто меняю имя кодовой таблицы и QT автоматом перекодирует содержимое файлов help, что бы они правильно отображались в окне консоли.

mOleg писал(а):
.... тут есть непонятый автором момент.

В SPF много хороших и разных библиотек по работе с DLL. Но им не хватает кросплатформенности и хорошего описания, да и потом хотелось понять суть процесса.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 19:22 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4999
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 20 раз.
Поблагодарили: 58 раз.
mgw писал(а):
В SPF много хороших и разных библиотек по работе с DLL.

не заметил.

mgw писал(а):
Но им не хватает кросплатформенности

они вобщем-то и не могут быть кроссплатформенными.
Хотя я свой вариант нашел.

mgw писал(а):
и хорошего описания, да и потом хотелось понять суть процесса.

да, описания к сожалению не хватает хорошего, но мне пришлось "раскопки" делать. Вобщем-то там ничего сложного, просто коряво сделано.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 19:52 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
По правильному надо все основные библиотеки тестировать на кроссплатформенность. Это наиболее острая проблема в SPF.
Хотя что считать основными библиотеками, для всех фортеров они различны. :(

Перенес FQT.DLL на MinGW из поставки QtCreator (версия QT 4.5.2). Всё работает нормально


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 20:00 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4999
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 20 раз.
Поблагодарили: 58 раз.
mgw писал(а):
По правильному надо все основные библиотеки тестировать на кроссплатформенность. Это наиболее острая проблема в SPF.

ну, далеко не все, а те, которые работают с АПИ. Но речь таки шла о методах вызова и связывания АПИ. А основная проблема СПФа в том, что от его модерирования отказался автор.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Пн янв 10, 2011 20:17 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
mOleg писал(а):
от его модерирования отказался автор.

А кто сейчас этим занимается? А что тогда за рассылка Spf-dev mailing list?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Ср янв 12, 2011 19:21 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4999
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 20 раз.
Поблагодарили: 58 раз.
mgw писал(а):
А кто сейчас этим занимается?

любой желающий из списка в devel. В последнее время это ygrek, если не ошибаюсь.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Статья: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Ср янв 12, 2011 22:30 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
В разработке FQT.DLL (windows) пришлось перейти на С++ MinGW, который свободно распространяется вместе с современным дистрибутивом QT. Без MinGW собрать современную QT нельзя. С++ MSVC 6.0 современной версией QT не поддерживается. MinGW хорош ещё тем, что совместим с gcc (Linux).


Новая версия для Windows (Qt 4.5.2 MinGW (QtCreator) http://mgw.narod.ru/spfqt_win.zip

Новая версия для Linux (Qt 4.5.7 gcc) http://mgw.narod.ru/spfqt_linux.zip


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Чт янв 20, 2011 19:34 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Нужен совет.
Сейчас для работы с графическими объектами используется библиотека ~day\hype3\hype3.f По умолчанию её синтаксис работы с методами объектов, это пробел:
Код:
  qs1 create       // Строка QString
  te1 create       // Редактор QTextEdit
  S" Привет МИР!!!" DROP qs1 set qs1 @ te1 append
  te1 show

Мне он не нравится, т.к. тяжело визуально понять, где объект, а где его метод. Думаю при помощи слова NOTFOUND реализовать синтаксис через точку:
Код:
  qs1.create       // Строка QString
  te1.create       // Редактор QTextEdit
  S" Привет МИР!!!" DROP qs1.set qs1.@ te1.append
  te1.show

Вопросы:
1 - не будет ли конфликтов с структурами
2 - может вместо точки другой символ ... какой?
3 - помогите написать определение NOTFOUND


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Чт янв 20, 2011 20:06 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 4999
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 20 раз.
Поблагодарили: 58 раз.
вопервых, уже есть вариант в ядре (к сожалению) вида :: поищите два двоеточия подряд в примерах.
Во-вторых, зря вы, лучше имена объектам понятные давать.
Проблема Форта в том, что из него все хотят сделать неФорт.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Подключение графической библиотеки QT к SPF 4.20
СообщениеДобавлено: Чт янв 20, 2011 23:33 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Положил на сайт улучшенную версию библиотеки. Не всё получается, как задумано :cry:
http://mgw.narod.ru/spfqt_win.zip


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 82 ]  На страницу 1, 2, 3, 4, 5, 6  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB