Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Продвинутая работа с dll в mdm Zinc, winAPI Zinc dll
chingachgoog
сообщение 12.01.2011 - 19:11
Сообщение #1


Ветеран конференции
*****

Группа: Пользователь
Сообщений: 1179
Регистрация: 27.02.2009
Из: Moscow
Пользователь №: 9144



Zinc позволяет чудесно использовать dll-ки 1
Причем спокойно можно использовать стандартные виндовые библиотеки, т.е. winAPI. Таким образом приложения на Цинке становяться практически неотличимыми по функционалу от приложений написанных на низкоуровневых языках типа Си и Дельфи. И ничто бы не портило этой радужной картины, кабы не ограничения работы Цинка с dll-ками.

Цинк передает и принимает параметры из функций dll в виде простых значений (по сути строк). Это сильно ограничивает возможности работы с dll, т.к. многие функции winAPI, например, принимают и возвращают сложные данные (например, структуры). Единственным известным мне решением до недавнего времени оставалось использовать dll-прокладок (медиаторов) между Цинком и "сложными" dll-ками. Писались эти прокладки на Дельфи, либо Сях, что делало их доступность для ActionScript-программистов весьма сомнительной. К тому же надо было подготавливать специальный интерфейс для общения с медиатором. Вообщем дело крайне утомительное.

И вот тут что-то упало на голову (яблоко? smile.gif ). Портируя очередную функцию с си, я вдруг заметил то, что давно было перед глазами. Это постоянно используется в сях - передача не значения, а адреса памяти (ссылки) где хранится значение (любой сложности!). Принцип решения был найден - осталось "всего лишь" воплотить его в жизнь smile.gif И тут бы я и остался бы с розовыми мечтами, если бы не наводка моего товарища tortMaker-а и огромнейшая помощь от alexcon314, который в общем-то и решил эту задачу.

Собственно решение.

Используется стандартная библиотека msvcrt.dll и три функции в ней:
malloc - резервируем необходимое число байтов (памяти) и получаем адрес первого из них.
memset - записываем значение(я) с выбранного адреса памяти
memcpy - возращает значение из указанного адреса памяти (возвращается строка чаров, но только до первого нулевого символа и порой в "перевернутом виде")

Код
msvcrt = new mdm.DLL(mdm.System.Paths.windows+"/system32/msvcrt.dll");
////////////////////////////////////////////
//       Определяем имя пользователя      //
////////////////////////////////////////////

function getUserName(){
    msvcrt.clear()        
    msvcrt.addParameter("integer", 0xff);
    var memU = msvcrt.call("integer", "malloc");
    
    msvcrt.clear();         
    msvcrt.addParameter("integer", 4);
    var memN = msvcrt.call("integer", "malloc");
    
    msvcrt.clear();
    msvcrt.addParameter("integer", memN);
    msvcrt.addParameter("integer", 0xff);
    msvcrt.addParameter("integer", 1);
    msvcrt.call("integer", "memset");
    
    advapi32.clear(); // BOOL WINAPI GetUserName( __out    LPTSTR lpBuffer, __inout  LPDWORD lpnSize);
    advapi32.addParameter("integer", memU);
    advapi32.addParameter("integer", memN);
    var b = advapi32.call("boolean","GetUserNameA");

    advapi32.clear();
    
    msvcrt.clear(); // void *memcpy( void *dest, const void *src,  size_t count );
                                    // dest - New buffer.
                                    // src - Buffer to copy from.
                                    // count - Number of bytes to copy.
                                    // Return Value - The value of dest.
    msvcrt.addParameter("integer", memU); // адрес нового буфера
    msvcrt.addParameter("integer", memU); // адрес буфера из которого копируем (сам себя)
    msvcrt.addParameter("integer", 0xff); // число байтов которые копируем
    var u = msvcrt.call("string", "memcpy"); // возвращаемое значение из нового буфера

    msvcrt.clear();
    msvcrt.addParameter("integer", memU);
    msvcrt.call("integer", "free");

    msvcrt.clear();
    msvcrt.addParameter("integer", memN);
    msvcrt.call("integer", "free");
    
    msvcrt.clear();
    
    return u
}


Вообщем работаем с winAPI практически без ограничений!

1 Цинк работает с классом DLL с рядом ограничений:
- ограничение по платформе. Это либо Винда, либо Линукс (но Цинк проект должен быть тогда версии 3, скомпилирован под Винду(!) и запущен на Линуксе через WINE)
- ограничение по типу dll. Библиотеки могут быть только win32-типа, com и .NET не выполняются.


--------------------
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
tiHo
сообщение 12.01.2011 - 20:32
Сообщение #2


C:\>
*****

Группа: Супермодераторы
Сообщений: 1604
Регистрация: 10.04.2006
Из: Млечный Путь, 3-я планета от Солнца, Россия, Московская область, Жуковский.
Пользователь №: 293



интересно, спасибо за информацию.


--------------------
Вопрос-ответ для flash-разработчиков
С тех пор, как за Теорию Относительности принялись математики, я ее сам больше не понимаю. (с) Эйнштейн А.
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
MustLive
сообщение 13.01.2011 - 00:21
Сообщение #3


Ветеран конференции
*****

Группа: Flash Zone Team
Сообщений: 4952
Регистрация: 10.03.2005
Из: Киев
Пользователь №: 5



Цитата
Zinc позволяет чудесно использовать dll-ки

Работа из флеша с dll и WinAPI (через Zinc в данном случае) - это весьма интересно. И при использовании флеша для создания десктопных приложений может весьма пригодиться. Когда нужно использовать не только возможности самого флеша (т.е. просто сделать exe-проект из флешки), а когда нужно сделать полноценное приложение (например работающее с WinAPI).

Молодец chingachgoog, который с товарищами tortMake и alexcon314 разработали данный алгоритм работы, который позволяет обходить ограничения Zinc (в частности на передачу параметров функций). Данная информация без сомнения пригодиться людям wink.gif.

Цитата
низкоуровневых языках типа Си и Дельфи

Когда это Си и Дельфи стали низкоуровневыми smile.gif. Это высокоуровневые языки - согласно официальному разделению на языки низкого, высокого и сверхвысокого уровня. А учитывая большие низкоуровневые возможности в Си, его иногда ещё называют языком среднего уровня. Низкий уровень - это уже ассемблер. Ниже только байт коды и машинные коды.


--------------------
Best wishes & regards,
MustLive
Администратор сайта
http://mlfun.org.ua
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
Chaos
сообщение 27.02.2011 - 02:56
Сообщение #4


Новичок
*

Группа: Новичок
Сообщений: 2
Регистрация: 27.02.2011
Из: Питер
Пользователь №: 10355



респект!)
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
Varcharamir
сообщение 4.02.2012 - 08:33
Сообщение #5


Новичок
*

Группа: Новичок
Сообщений: 2
Регистрация: 4.02.2012
Пользователь №: 10866



Скажите пожалуйста, как после этого использовать полученную ссылку. Я представляю, что ссылка отправляется в виде параметра (строки) в Зинк, но как из флэша-зинка работать с сылкой? Там, видимо, есть какая-то простая функция о которой я не знаю. И хотелось бы уточнить, есть ли альтернативные решения для Zinc 4.0. mdm во всю хвалились его способностью работать со всеми возможными параметрами, но я пока не могу понять на сколько это правда. Т.е. вопрос в том, отпала ли необходимость в таких ухищрениях с новым Зинком?
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
chingachgoog
сообщение 7.02.2012 - 21:50
Сообщение #6


Ветеран конференции
*****

Группа: Пользователь
Сообщений: 1179
Регистрация: 27.02.2009
Из: Moscow
Пользователь №: 9144



Как использовать ссылку полностью объяснено в примере. )))

Что касается 4-го Цинка, то судя по лайвдокам класс работы с dll остался без изменений. Так что все актуально по-прежнему.


--------------------
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
Varcharamir
сообщение 16.02.2012 - 08:44
Сообщение #7


Новичок
*

Группа: Новичок
Сообщений: 2
Регистрация: 4.02.2012
Пользователь №: 10866



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

У меня еще есть несколько вопросов. Мне необходимо передать ссылку на функцию, как параметр. В C++ она бы вызывалась, как function1(&function2). Обе функции void (т.е. ничего не возвращают). Как я понимаю, мне надо передать указатель на начало функции function2. Что-то вроде mydll.addParameter("integer", function2); , а затем кинуть ее в функцию mydll.call("none", "function1");. Но я почти уверен, что так просто не выйдет.

И второй вопрос можно ли как-то достать глобальную переменную из dll-ки все так же не меняя библиотеку и не подгружая ее в Zinc? Т.е можно ли это сделать без создания дополнительной функции, которая бы возвращала эту переменную, как ответ на запрос?

Сообщение отредактировал Varcharamir - 16.02.2012 - 08:50
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
chingachgoog
сообщение 17.02.2012 - 16:08
Сообщение #8


Ветеран конференции
*****

Группа: Пользователь
Сообщений: 1179
Регистрация: 27.02.2009
Из: Moscow
Пользователь №: 9144



Не, работает не так. Просто попробуйте воспроизвести этот пример.

Без этих функций не обойтись:

malloc - после call("integer", "malloc") получаем адрес первого из зарезервированных байтов.
memset - call("integer", "memset") записываем значение(я) с выбранного адреса памяти. Не помню, почему там возращаемое значение integer, а не none. Может и none проатит )))
вызов основной функции с параметрами... Только тут моет быть любая функция, которая нам нужна ...
memcpy - call("string", "memcpy") возращает значение (строка) из указанного адреса памяти (того, что мы получили в call("integer", "malloc"))

Цитата(Varcharamir @ 16.02.2012 - 09:44) *
И второй вопрос можно ли как-то достать глобальную переменную из dll-ки все так же не меняя библиотеку и не подгружая ее в Zinc? Т.е можно ли это сделать без создания дополнительной функции, которая бы возвращала эту переменную, как ответ на запрос?


Весь вопрос КУДА ее нужно достать? Если во флеш/Цинк, то как они ее прочтут/достанут, если вообще об этой переменной не знают? Только если в самой dll будет механизм доставки ее во флеш/Цинк - например, через LocalConnection.


--------------------
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия Сейчас: 3.07.2014 - 07:18