Вверх ↑
Этот топик читают: Гость
Ответов: 963
Рейтинг: 12
#31: 2014-12-04 12:04:03 ЛС | профиль | цитата
andrestudio писал(а):
AlexKir, я тоже работал над темой когда то

У меня вообще с этого "хайасматика" начиналась ...

Давным давно.
В далеком 2005-том ...
http://forum.hiasm.com/forum.html?q=3&t=5179
Кстати и паскаль-скрипт(интерпретатор паскаля) я все же к хайасму тоже прикрутил ...


карма: 0

0
Ответов: 5227
Рейтинг: 588
#32: 2014-12-04 15:47:42 ЛС | профиль | цитата
AlexKir писал(а):
В далеком 2005-том ...
http://forum.hiasm.com/forum.html?q=3&t=57073
Кстати и паскаль-скрипт(интерпретатор паскаля) я все же к хайасму тоже прикрутил ...

AlexKir, Спасибо за рекламу т.к это моя ветка
карма: 4
Мой форум - http://hiasm.bbtalk.me/ схемы, компоненты...
0
Ответов: 963
Рейтинг: 12
#33: 2014-12-04 17:02:40 ЛС | профиль | цитата
andrestudio писал(а):
Спасибо за рекламу т.к это моя ветка


"Я волком бы выгрыз идиотизм".. начиная разумеется с себя...
Опечатка...
http://forum.hiasm.com/forum.html?q=3&t=5179
Зы
Но вопрос весит себе дальше :
Так что исходящими есть более элегантный способ вернуть данные в поток ?
(с использованием названия точки )
карма: 0

0
Ответов: 4621
Рейтинг: 746
#34: 2014-12-04 17:39:49 ЛС | профиль | цитата
Что ты имеешь в виду? В твоей схеме с VisualInline выдать данные на правую точку компонента?
Или точнее, вызвать в коде событие правой точки, чтоб результат вызова впечатался в место вызова?
карма: 26

0
Ответов: 963
Рейтинг: 12
#35: 2014-12-04 18:18:00 ЛС | профиль | цитата
Netspirit писал(а):

Что ты имеешь в виду? В твоей схеме с VisualInline выдать данные на правую точку компонента?
Или точнее, вызвать в коде событие правой точки, чтоб результат вызова впечатался в место вызова?

Не просто выдать"выдать данные на правую точку компонента"(контейнераFTCG) это уже есть(http://forum.hiasm.com//getfile/34710) а вызов по имени точки а не по номеру..
Да и линию связи не плохо бы сохранить
[flood]в коде нет использования данных с onPrint
Функция тело которой упрятано в VI вызывается как процедура
Возможно есть еще какой-то способ но я нашел .

[/flood]

карма: 0

0
Ответов: 4621
Рейтинг: 746
#36: 2014-12-04 18:27:57 ЛС | профиль | цитата
В пакете Delphi не предусмотрено в runtime вызывать события MultiElementEx по имени точки. События компонента типа MultiElementEx представляют собой массив, обращение к элементам которого идет по индексам, что ты и продемонстрировал.
Имена точек существуют на этапе кодогенерации. Повлиять на кодогенерацию можно либо изменив кодогенератор (и код компонентов в *.pas файлах), либо в случае компонентов FTCG - изменив код компонентов в файлах *.hws. Например, можно вызывать VisualInline.onPrint внутри кода (а не после).
карма: 26

0
Ответов: 1841
Рейтинг: 369
#37: 2014-12-04 18:30:10 ЛС | профиль | цитата
А я вот в свободное время, пытаюсь придумать механизм интеграции IC на C/C++...
Или хотя бы, подключение библиотек в "один клик"
Пытался реализовать свою библиотеку с интерфейсом HiDLL на основе UseHiDLL, и даже многое получилось, но, среда никак не хочет корректно обрабатывать некоторую информацию переданную ей через механизмы C++.
Ох уж этот Delphi...
карма: 1
0
Ответов: 963
Рейтинг: 12
#38: 2014-12-04 18:55:19 ЛС | профиль | цитата
CriDos писал(а):
Или хотя бы, подключение библиотек в "один клик"
Пытался реализовать свою библиотеку с интерфейсом HiDLL на основе UseHiDLL, и даже многое получилось, но, среда никак не хочет корректно обрабатывать некоторую информацию переданную ей через механизмы C++.
Ох уж этот Delphi...


Там вроде должен быть ключ Pascal при объявлении функций в c++

карма: 0

0
Ответов: 1841
Рейтинг: 369
#39: 2014-12-04 19:00:25 ЛС | профиль | цитата
AlexKir писал(а):
Там вроде должен быть ключ Pascal при объявлении функций в c++

Вроде как __fastcall
Надо будет сейчас проверить с различными соглашениями, но вроде, у borland __fastcall используется...
карма: 1
0
Ответов: 4621
Рейтинг: 746
#40: 2014-12-04 19:02:15 ЛС | профиль | цитата
Нет, pascal (или register).
карма: 26

0
Ответов: 963
Рейтинг: 12
#41: 2014-12-04 19:10:29 ЛС | профиль | цитата
Имена точек существуют на этапе кодогенерации. Повлиять на кодогенерацию можно либо изменив кодогенератор (и код компонентов в *.pas файлах), либо в случае компонентов FTCG - изменив код компонентов в файлах *.hws. Например, можно вызывать VisualInline.onPrint внутри кода (а не после).

VisualInline.onPrint ?
В FTCG (Если я верно понял ) каждый элемент в контейнере функция ...
А потом просто взывают их по очереди или один как параметр другого .
Код в теле VisualInline вызывают как ПРОЦЕДУРУ ....

Поправить элемент не проблема... но теряется совместимость схем ..
карма: 0

0
Ответов: 1841
Рейтинг: 369
#42: 2014-12-04 22:54:47 ЛС | профиль | цитата
Флуд не по теме
Netspirit писал(а):
Нет, pascal (или register).

Тут не всё так просто
Я изначально использовал соглашение «extern "C" __cdecl».
После неудачных попыток передачи УКАЗАТЕЛЯ по ССЫЛКЕ (*&):
#pas
procedure _hi_PointsInfo(var _prop_WorkPoints,_prop_EventPoints,_prop_VarPoints,_prop_DataPoints:PChar); export;
, решил поиграться с соглашениями и глянуть, чего там объявлено в windows.h.Там имеем #define PASCAL __stdcall, но, нам не подходит, т.к. HiAsm не увидит экспортированные функции из-за декоратора имён (_Z14_hi_PointsInfoRPcS0_S0_S0_@16)...
В попытке решить данную проблему, делаем «#define EXPORT extern "C" PASCAL» и получаем "_hi_PointsInfo@16", т.е. декорированное имя, хотя и короче

ОК, пробуем получить параметры из HiAsm библиотеки в C++.
Подключаем HiDLL.def к проекту:
#cpp
EXPORTS
_hi_PointsInfo=_hi_PointsInfo@16

#cpp
#define DLL_IMPORT extern "C" PASCAL
typedef char *PChar;

DLL_IMPORT void _hi_PointsInfo(PChar &workPoints,
PChar &eventPoints,
PChar &varPoints,
PChar &dataPoints);
int main(int argc, char *argv[])
{
//На всякий случай выделим памяти, вдруг чего :lol:
PChar t1 = new char[255]{};
PChar t2 = new char[255]{};
PChar t3 = new char[255]{};
PChar t4 = new char[255]{};;

_hi_PointsInfo(t1, t2, t3, t4);

//t1 = "doWork" - УРА, записалось :lol:
//t2 = "" - пусто :(
//t3 = "" - пусто :(
//t4 - падаем :D


return 0;
}


А вот собственно экспортируемая функция HiAsm dll, которая и передать указатель на массив по ссылке:
#pas
procedure _hi_PointsInfo(var _prop_WorkPoints,_prop_EventPoints,_prop_VarPoints,_prop_DataPoints:PChar); export;
begin
_prop_WorkPoints := PChar('doWork'#0);
_prop_EventPoints := PChar('onEvent'#0);
_prop_VarPoints := PChar('Var'#0);
_prop_DataPoints := PChar('Data'#0);
end;
У меня собственно вопрос к знатокам Delphi/FPC.
Зачем использовать ссылку на указать на массив из char'ов?
------------ Дoбавленo в 23.40:
Понял для чего ссылка на указатель.
Мы получается, передаём переменной _prop_WorkPoints (ссылка t1) указатель на начало массива из char в стеке, т.е. не сделали нормально и не выделили из кучи место под массив, а взяли и вернули указатель на строку из стека...

CriDos писал(а):
procedure _hi_PointsInfo(var _prop_WorkPoints,_prop_EventPoints,_prop_VarPoints,_prop_DataPointsChar);

Причём вот тут, как я понимаю, аргументы _prop_VarPoints (которые без var) передаются по значению? Т.е. меняется содержимое локальной копии переменной?
------------ Дoбавленo в 23.54:
CriDos писал(а):
_prop_VarPoints (которые без var)

Забывать уже начал, особенность синтаксиса передачи аргументов паскаля
Все ссылки, однако...
карма: 1
0
Ответов: 4621
Рейтинг: 746
#43: 2014-12-05 12:42:51 ЛС | профиль | цитата
[offtop]
CriDos писал(а):
указатель на начало массива из char в стеке, т.е. не сделали нормально и не выделили из кучи место под массив, а взяли и вернули указатель на строку из стека...
А в стек оно откуда попадет? Как я понимаю, тут используется та особенность, что строковые константы жестко прописываются в исполняемом файле, и к тому же константы не подвергаются механизму подсчета ссылок. Поэтому "массив из char" всё же лежит не в стеке и не уничтожается после выхода из процедуры, поэтому его адреса остаются валидными.

А вообще, в таких случаях вызывающий сам готовит буфер, передаёт его адрес в dll, а она туда копирует нужные данные. Так работает Windows API. Ну и ещё в dll может быть возможность предварительно узнать требуемый размер буфера. Также dll может сама выделять буфер, но предоставлять функцию для его освобождения, когда данные больше не нужны.[/offtop]
карма: 26

0
Ответов: 1841
Рейтинг: 369
#44: 2014-12-05 20:43:33 ЛС | профиль | цитата
[offtop]
Netspirit писал(а):
Поэтому "массив из char" всё же лежит не в стеке и не уничтожается после выхода из процедуры, поэтому его адреса остаются валидными.

Так то и я думал, но, что то оно как то не так работает в данном случае, видимо
Или с вызовами что то.

Netspirit писал(а):
А вообще, в таких случаях вызывающий сам готовит буфер, передаёт его адрес в dll, а она туда копирует нужные данные. Так работает Windows API. Ну и ещё в dll может быть возможность предварительно узнать требуемый размер буфера. Также dll может сама выделять буфер, но предоставлять функцию для его освобождения, когда данные больше не нужны.

Я про это и говорю, что не надо было делать так, как сейчас сделано.

Попробую сейчас в lazarus сделать аналогичный функционал и глянуть, чего там в памяти творится.[/offtop]
------------ Дoбавленo в 19.26:
[offtop]Вот, потихоньку всё встаёт на свои места
На стеке вызовов фигня творится.
В случае, если обе стороны используют cdecl, всё ок, передаются корректные адреса переменных, но, как только паскалевская библиотека экспортирует процедуру с ключевым словом export, пиши пропало, из C++ никак не могу корректно передать в неё данные...
Буду дальше копать [/offtop]
------------ Дoбавленo в 20.13:
[offtop]Всё же я оказался прав относительно fastcall
wiki писал(а):

В компиляторе Borland, для соглашения __fastcall, называемого также register[5], параметры передаются слева направо в eax, edx, ecx и, если параметров больше трёх, в стеке, также слева направо. Указатель стека на исходное значение возвращает вызываемая подпрограмма.

Fastcall Borland применяется по умолчанию в Delphi.

Соглашение __fastcall Microsoft, также называемое __msfastcall, в 32-разрядной версии компилятора Microsoft[6], а также компилятора GCC[7], определяет передачу первых двух параметров слева направо в ecx и edx, а остальные параметры передаются справа налево в стеке. Очистку стека производит вызываемая подпрограмма.

Осталось корректно передать параметры с учётом соглашения и можно попробовать сделать шаблон компонента
[/offtop]

------------ Дoбавленo в 21.43:
[offtop]Ох и намудрили с этими вызовами
Решил таки сию задачу.

Вот так вот следует объявлять прототип внешней registerexport (fastcall) функции в C++ GNU (GCC):
#cpp
extern "C" __attribute__((regparm(3))) void _hi_PointsInfo(PChar &t1, PChar &t2, PChar &t3, PChar &t4);

Или если вы используете Qt:
#cpp
extern "C" QT_FASTCALL void _hi_PointsInfo(PChar &t1, PChar &t2, PChar &t3, PChar &t4);

Вызовы корректно конвертируются и возможно использовать более 3 аргумента
[/offtop]
карма: 1
1
Голосовали:Nic
Ответов: 963
Рейтинг: 12
#45: 2014-12-06 00:28:43 ЛС | профиль | цитата
Уже попробовал "боевое применение" VI ...
Опыта пока что мало но уже виден потенциал ....

nhed_3e.zip
(Это я начал с нуля переписывать шестнадцатеричный редактор
Сделал пока только просмотр... VI вначале было чуть больше но решил "тише едешь дальше будешь" )
Недостатки реализации VI бросаются в глаза
1 В контейнер можно помещать только один VI
2 Явно недостаточно одной входящей точки .
3 Про исходящие уже писал .
4 Среда чуть подглюкивает например если поле редактора активно и нажать выход
на верхний уровень редактор остается висеть поверх схемы ...
карма: 0

0
файлы: 1nhed_3e.zip [72KB] [353]
Сообщение
...
Прикрепленные файлы
(файлы не залиты)