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

...
Google Search
Forth-FAQ Spy Grafic

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




Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Чт фев 18, 2010 11:26 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Пишут, что при вызове конструктора C++ ему неявно передается адрес (this) на область памяти. Предположим, что есть конструктор (Obj::Obj(int p1, int p2))с двумя параметрами, его адрес в DLL известен, и адрес свободной области Adr.
Вопросы:
1 – в какой последовательности в стек закладывать параметры? Адрес области в начале или в конце списка?
2 – возвращает ли конструктор что то на стек, или нет?

Желательно пример на SPF


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт фев 18, 2010 16:57 
Не в сети
Аватара пользователя

Зарегистрирован: Вт сен 11, 2007 11:07
Сообщения: 187
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
это всё зависит от компилятора и его ключей, надо на него документацию читать. чаще всего this передают в ecx.
Код:
class xxx { public: xxx(int a1, int a2) {} }
main() { xxx a(1,2); }

примерно так
Код:
    push    2
    push    1
    lea ecx, DWORD PTR _a$[ebp]
    call    ??0xxx@@QAE@HH@Z            ; xxx::xxx
......
??0xxx@@QAE@HH@Z PROC NEAR              ; xxx::xxx, COMDAT
; Line 1
    push    ebp
    mov ebp, esp
    push    ecx
    mov DWORD PTR _this$[ebp], ecx
......
    mov eax, DWORD PTR _this$[ebp]
    mov esp, ebp
    pop ebp
    ret 8


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт фев 18, 2010 20:46 
Не в сети

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт фев 18, 2010 22:42 
Не в сети

Зарегистрирован: Чт май 04, 2006 18:18
Сообщения: 456
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Стандартная практика - на стороне c++ обернуть конструкторы и методы в сишные функции с дополнительным opaque параметром (this) и из форта вызывать эти функции. Меньше зависимости от настроения плюсового компилятора (и манглера имён).

_________________
http://forth.org.ru/~ygrek


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт фев 19, 2010 11:02 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Спасибо garbler! У меня получилось вызвать и конструктор с указанием на свободную область и метод класса MSVC6.0. Нужно это для того, что бы впрямую юзать C++ библиотеки минуя процедуру создания промежуточной DLL. С другой стороны мне не понятно, почему фортеры как то не замечают Qt. Даже если создать небольшую, экспериментальную связку с Qt, это значительно подняло бы интерес


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт фев 19, 2010 19:34 
Не в сети
Moderator
Moderator

Зарегистрирован: Ср май 10, 2006 15:37
Сообщения: 1132
Откуда: Chelyabinsk ( Ural)
Благодарил (а): 0 раз.
Поблагодарили: 9 раз.
mgw писал(а):
... С другой стороны мне не понятно, почему фортеры как то не замечают Qt. Даже если создать небольшую, экспериментальную связку с Qt, это значительно подняло бы интерес


Небольшой поиск по i-net вывел
Qt-Forth - учебный forth с графикой Qt для Windows и Linux

P.S. :) Пожоже это Ваше.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт фев 19, 2010 22:15 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
mgw писал(а):
С другой стороны мне не понятно, почему фортеры как то не замечают Qt. Даже если создать небольшую, экспериментальную связку с Qt, это значительно подняло бы интерес

http://www.msyst.ru/Euroforth2009.pdf


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Сб июл 13, 2013 16:53 
Не в сети

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

Задача: Подключится из SPF напрямую к DLL на C++, произвести наследование C++ класса средствами SPF с перекрытием виртуальных функций и добавлением собственных методов и свойств.
Для работы с DLL используем библиотеку ~mgw\mgw_dll.f. В качестве исследования возьмем QtGui.dll.
При помощи утилиты c++filt.exe, входящей в компилятор mingw C++ найдем функции конструкторов и методов.
Код:
REQUIRE _-Call" ~mgw/mgw_dll.f
Library" QtGui4.dll"  QtGui
\ QApplication( int & argc, char ** argv )
Library@ QtGui 2 THIS-CDECL-Win-MinGW-Call" _ZN12QApplicationC1ERiPPc" QApplication:QApplication
\ int QApplication::exec() 
Library@ QtGui 0 THIS-CDECL-Win-MinGW-Call" _ZN12QApplication4execEv" QApplication:Exec
\ QWidget::QWidget ( QWidget * parent = 0, Qt::WindowFlags f = 0 )
Library@ QtGui 2 THIS-CDECL-Win-MinGW-Call" _ZN7QWidgetC1EPS_6QFlagsIN2Qt10WindowTypeEE"  QWidget:QWidget
\ void QWidget::show()
Library@ QtGui 0 THIS-CDECL-Win-MinGW-Call" _ZN7QWidget10setVisibleEb" QWidget:show

Что бы вызвать конструктор надо ему передать адрес буфера в котором он будет размещать данные экземпляра. Пока я вычисляю этот размер функцией C++
Код:
cout << sizeof(QWidget);

Размер для QApplication=8, для QWidget=20.
Используем поддержку объектов из ~day\hype3\hype3.f
Код:
CLASS fQApp 8 CONSTANT fQAppSize
    fQAppSize DEFS ->fQApp    \ Буфер под эеземпляр QApp
: Create (A A -- A ) ->fQApp QApplication:QApplication DROP ;
: Exec  ( -- )    ->fQApp QApplication:Exec  DROP  ;
;CLASS

VARIABLE Qt:WinFl 0 Qt:WinFl ! \ Параметры QWidget, моделируем их …
CLASS fQWidget 20 CONSTANT fQWidgetSize
    fQWidgetSize DEFS ->fQWidget \ Буфер под эеземпляр QWidget
    CELL PROPERTY aOnResize
     ;
: Create  Qt:WinFl 0 ->fQWidget QWidget:QWidget DROP 
     ;
: show  ( -- )        \ Отобразить виджет на экране
    TRUE ->fQWidget QWidget:show DROP DROP
    ;
;CLASS

fQApp NEW genaQApp   \ Создать экземпляр QApp
fQWidget NEW w1      \ А это окно
fQWidget NEW w2      \ а это второе окно

: zz  \ Отобразить два окна на экране
    w1.Create w1.show   
    w2.Create w2.show
;

\ Основная функция
: main
   LibraryLoad QtGui   \ Загрузить библиотеку
   GetCommandLineA ASCIIZ> args SWAP aARGC ! aARGC \ Входные параметры для QApp
   genaQApp.Create   \ Вызов конструктора
   zz
   genaQApp.Exec
;

Результат работы, это два окна на экране. Причем мы не используем промежуточные «оберточные» DLL типа FQT.DLL как в первом моём варианте работы с Qt, а подключаемся прямо к объектной библиотеке.

Далее вопрос, как быть с виртуальными функциями, обслуживающими события? На помощь пришла vtbl[], таблица виртуальных функций. Располагается она как правило в первом слове буфера самого объекта. Я обратил внимание, что в самой QtGui.DLL присутствуют вызовы виртуальных функций, но как правило, они пустые и предназначены для перекрытия в новых классах C++. А раз так, то вызов виртуальной функции должен быть и в vtbl[].
Как найти? Я искал следующим образом. Надо вычислить адрес виртуальной функции, например void QWidget::resizeEvent ( QResizeEvent * event )
Код:
Library@ QtGui  Extern" _ZN7QWidget11resizeEventEP12QResizeEvent" QWidget:resizeEvent

Теперь у нас есть адрес виртуальной функции, которю мы будем искать в vtbl[]
Сама vtbl[] как правило расположена в начале данных экземпляра.
Код:
         +-------------+
         |             |
         +-------------+
         |             |               . . .       -------> Вторая и т.д.
         +-------------+  vtbl[]   +-------------+
         |             |---------> |             | -------> Первая виртуальная функ
Буфер -> +-------------+           +-------------+
экземпляра объекта.

Дальше просто поиск в памяти. Типа:
Код:
w1.->fQWidget @ смещение + @ QWidget:resizeEvent = \ истина, значит нашли.

Для моего варианта QtGui.DLL оказалось, что resizeEvent в 33 ячейке vtbl[]
Модернизируем класс fQWidget, для работы с виртуальной функцией.
Код:
: <<!    // ( Avar -- ) Записать xt послед скомпил вслова в переменную Avar
      LATEST NAME> SWAP !
     ;
VARIABLE Qt:WinFl 0 Qt:WinFl ! \ Параметры QWidget, моделируем их …
CLASS fQWidget 20 CONSTANT fQWidgetSize
    fQWidgetSize DEFS ->fQWidget \ Буфер под эеземпляр QWidget
    CELL PROPERTY aOnResize
     ;
: Create  Qt:WinFl 0 ->fQWidget QWidget:QWidget DROP 
     ;
: show  ( -- )        \ Отобразить виджет на экране
    TRUE ->fQWidget QWidget:show DROP DROP
    ;
\ Это наш саллбак который перекроет виртуальную в vtbl[]
VARIABLE aonResizeEvent :NONAME
      S" !!!" TYPE CR ; 0 CELLS CALLBACK: onResizeEvent aonResizeEvent <<!
: ЗаменитьВиртуальнуюНаНашу
    aonResizeEvent @ ->fQWidget @ 33 ( смещение в vtbl[] ) CELL * + !
    ;
;CLASS

: zz  \ Отобразить два окна на экране
    w1.Create w1.show w1.ЗаменитьВиртуальнуюНаНашу  \ меняем виртуальную на нашу
    w2.Create w2.show
;

\ Основная функция
: main
   LibraryLoad QtGui   \ Загрузить библиотеку
   GetCommandLineA ASCIIZ> args SWAP aARGC ! aARGC \ Входные параметры для QApp
   genaQApp.Create   \ Вызов конструктора
   zz
   genaQApp.Exec
;

Результат работы, это два окна на экране, причем при изменении размера любого, в консоль идет вывод «!!!» как результат работы нашей функции, вместо виртуальной С++



За это сообщение автора mgw поблагодарил: Majestio
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Чт июл 18, 2013 12:12 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Не в тему, но меня сильно впечатлило!
Прочитал книгу: Андрей Александреску - язык программирования D. Она очень хорошо написана и в ней много актуальных и для форта тем. Кому надо, могу выслать файл pdf


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Чт июл 18, 2013 16:11 
Не в сети

Зарегистрирован: Пн янв 07, 2013 22:40
Сообщения: 2141
Благодарил (а): 8 раз.
Поблагодарили: 74 раз.
mgw писал(а):
Не в тему, но меня сильно впечатлило!
Прочитал книгу: Андрей Александреску - язык программирования D. Она очень хорошо написана и в ней много актуальных и для форта тем. Кому надо, могу выслать файл pdf

А чем то отличается от размещённой в i-nete по приведённому автору и названию (Символ плюс -2012) Перевод Данилиной 13,9Мб)
Haпример


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Пн авг 05, 2013 17:52 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Ура!!! Я научился делать слоты и вызывать сигналы Qt с форта без C++. Вся Qt как на ладони :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Пн авг 05, 2013 18:44 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
mgw писал(а):
Ура!!!

Ура!

А пример можно?
Что вышло СПФ-специфичного?

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Пн авг 05, 2013 19:06 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Специфики нет. Можно работать с любого языка умеющего делать машинный код (нужен для CallBack) и желательна поддержка ООП (без объектов тяжко думать). Сейчас я (в свободное от рутины время) делаю новую библиотеку. Рабочее название QtE - вроде как Extract из Qt.
Схема:
Программа --> Модуль_QtE --> QtE.DLL --> Qt
Модуль_QtE все что может берет прямо из QtCore.dll и QtGui.dll, а что не может то из QtE.dll
Не может вызов конструкторов и перекрытие виртуальных функций C++ ( в конечном итоге не компилятор C++ пишем ).
Пока 100 строчек в QtE.cpp и 300 строчек в Модуль_QtE, но нарастить до рабочего состояния можно быстро. Все принципы сейчас понятны.
Под впечатлением от языка D я пока делаю все на нем, но с прицелом на Forth.
В качестве примера небольшая прога на D, на форте будет так же + обратная запись.
Код:
/*------------------------------
Пример работы с QtE
-------------------------------*/
// win: dmd main.d qte.d -L/SUBSYSTEM:WINDOWS:5.01
// lin: dmd main.d qte.d -L-ldl

//  import std.c.stdio;
import qte;          // Работа с Qt
import core.runtime;

int main(string[] args) {
   // Цепляем библиотеки QtCore, QtGui, QtE.
   int rez = LoadQt(); if (rez==1) return 1;  // Ошибка загрузки библиотеки
   
   QApplication app = new QApplication;
   (app.adrQApplication())(cast(void*)app.bufObj, &Runtime.cArgs.argc, Runtime.cArgs.argv);

   gPushButton копка1 = new gPushButton(null, new QString("Нажми меня и узнай версию Qt"w));
        копка1.connect(копка1.QtObj(), MSS("clicked()", QSIGNAL),  app.QtObj(), MSS("aboutQt()", QSLOT), 1);

   копка1.show();
   return app.exec();
}

Отличие от моей предыдущей версии только строка:
копка1.connect(копка1.QtObj(), MSS("clicked()", QSIGNAL), app.QtObj(), MSS("aboutQt()", QSLOT), 1);
как пример связки сигнала и слота. Причем и те и другие можно реализовать без использования C++


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Пн авг 05, 2013 21:56 
Не в сети

Зарегистрирован: Ср фев 17, 2010 18:10
Сообщения: 323
Откуда: Тверь
Благодарил (а): 13 раз.
Поблагодарили: 11 раз.
Нужен совет.
Как правильно оформить библиотеку в рамках SPF. Наверное надо в виде модуля как то? Сам код логически делится на несколько частей:
---------------- уровень модулей -----------
1 — Описание таблицы адресов
2 — Описание классов.
---------------- уровень программы --------
3 — загрузить библиотеки
4 — создать объекты (экземпляры)
5 — логика работы с объектами

Был бы признателен за схему, например такого типа:
Код:
MODULE:
   Загрузка адресов .....
   Library@ libfqt 1 CDECL-Call" QT_QProgressBar" фQT_QProgressBar
EXPORT
   LoadLibrary libqte
MODULE;

CLASS fQObject
   1 CELLS PROPERTY adr_fQObject // Запомним адрес объекта
CLASS;

Вот в структуре MODULE .... MODULE; и CLASS .... CLASS; я путаюсь.

Как это все правильно оформить то?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Вызов из SPF конструктора C++ в DLL
СообщениеДобавлено: Вт авг 06, 2013 08:12 
Не в сети
Аватара пользователя

Зарегистрирован: Вт мар 20, 2007 23:39
Сообщения: 1261
Благодарил (а): 3 раз.
Поблагодарили: 19 раз.
mgw писал(а):
Нужен совет.
Как правильно оформить библиотеку в рамках SPF. Наверное надо в виде модуля как то?

Да, в виде обычного текстового файла.
mgw писал(а):
Вот в структуре MODULE .... MODULE; и CLASS .... CLASS; я путаюсь.

http://spf.sourceforge.net/docs/intro.ru.html#module
Еще в ~/devel имеет смысл заглянуть - там много различного рода библиотек и способов описания.
А версия под линукс будет? Тогда можно будет писать кросс-платформенные программы с Qt и спф.

_________________
Cтоимость сопровождения программного обеспечения пропорциональна квадрату творческих способностей программиста.
Роберт Д. Блисc


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

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


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

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


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

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