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


Собственно решение.
Используется стандартная библиотека 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
}
////////////////////////////////////////////
// Определяем имя пользователя //
////////////////////////////////////////////
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 не выполняются.