Cockney, ты использовал новый интерфейс плагинов с передачей результата по указателю? У меня пустоту возвращает хоть убей. Причем структуру создаю, все назначаю, старый вариант по всей цепочке указателей значение считывает нормально:
sprintf_s(ParamStruct->Result,
"%u " "%u " "%s", &ResultStruct.RArray, ParamStruct->pResultStruct, ParamStruct->pResultStruct->RArray
);
ResultStruct.used = true;
Игрался. Было раз такое, но это я с адресами тупил. сяду за комп - напишу код.
С адресами я тоже тупил. Точнее я думал структуру создаст пилот, а мне ее надо только принять, соответственно писал сначала в молоко и понять ничего не мог. Но сейчас вроде как все нормально сделано...
include <stdexcept>
using namespace std;
struct tInitStruct
{
long unsigned FunctionCount;
const char** FunctionNames;
};
struct tResultStruct // Заполняется плагином. Память под строку выделяется и освобождается плагином.
{
bool used; // Используется ли эта структура при возврате значения. = false
unsigned int RLength; // Размер данных.
char *RArray; // Указатель на возвращаемую строку.
unsigned int Reserved1;
unsigned int Reserved2;
unsigned __int64 Reserved3;
unsigned __int64 Reserved4;
};
tResultStruct ResultStruct;
struct tParamStruct
{
int unsigned* WindowHandle; // Handle of workWindow
int unsigned* WindowPID; // pid of process of workWindow
tResultStruct *pResultStruct;
char* ParamString; // string of parameters with substituted variables
char* ParamStringOrig; // original string of parameters
char Result[32767]; // array for returned values
};
tParamStruct *ParamStruct; // init by UOPilot
static tInitStruct InitStruct; // init by plugin, free on unload
extern "C" __declspec(dllexport) unsigned long * __stdcall InitPlugin(int App, int Scr, double& Version)
{
// Количество полезных экспортируемых функций для сообщения пилоту
// в зависимости от версии протокола обмена между пилотом и плагином.
// Это НЕ версия самого пилота, а версия протокола обмена между пилотом и длл.
if (Version >= 2.18)
{
InitStruct.FunctionCount = 2;
InitStruct.FunctionNames = new const char*[InitStruct.FunctionCount];
InitStruct.FunctionNames[0] = "Function1";
InitStruct.FunctionNames[1] = "Function2";
}
else
{
InitStruct.FunctionCount = 0; // Выгурзит длл, т.к. функций для экспорта нет.
}
return (&InitStruct.FunctionCount);
}
static char message[] = "123\0";
// Образец функции возвращающей строку.
extern "C" __declspec(dllexport) void __stdcall Function2(tParamStruct *ParamStruct)
{
// Так работает по старой схеме:
ResultStruct.RArray = message;
ResultStruct.RLength = 4;
ParamStruct->pResultStruct = &ResultStruct;
sprintf_s(ParamStruct->Result,
"%u " "%u " "%s", &ResultStruct.RArray, ParamStruct->pResultStruct, ParamStruct->pResultStruct->RArray
);
// Вот так пустоту возвращает:
ResultStruct.used = true;
ResultStruct.RArray = message;
ResultStruct.RLength = 4;
ParamStruct->pResultStruct = &ResultStruct;
}
Да.
А если так ? я не знаю, есть ли разница, но....
ParamStruct->pResultStruct = int(&ResultStruct);
т.к. в ParamStruct адрес данных идет в reserved, который является cardinal(в сях наверно int, или аналог), а ты адрес суешь сразу.
Вроде по размеру как бы совпадает, но то адрес прямой, а то число, хотя хз как там в си.
reserved был заменен на tResultStruct *pResultStruct;
Т.е. там натуральный указатель.
Он корректный, да, ты же знаешь, что он там находится, и считываешь с него. А вот пилот, думаю, не знает, и пытается ЧИСЛО привести к АДРЕСУ. А выходит, что он непонятные данные приводит к чему-то. Ну имхо. Попробуй с исходным reserved. и приведи адрес к инту. не упрощай с лету все.
дык адрес это и есть unsigned int. Он хранится как беззнаковое 4 байта, т.е. unsigned int. Запись указателя в инт на самом деле это не очень правильно. Т.е. компилятор скажет, что я не прав и нужно приведение, либо, как обычно и делается, сказать компилятору, что данные на самом деле нужного типа(int)pointer.
Кардинал это беззнаковый 4 байта?
Чет я в этой запаре уже пальцы заплетаются. Не крашит - пустоту возвращает.
Да.
Ты пробовал, как я писал?
Да, сейчас как раз сижу. Так же попробовал сделать ошибку записав адрес в знаковый инт - результат тот же.
Причем пустота возвращается какая-то странная. chrtohex пишет, что там вроде как пусто, но если сделать:
log $var
то в лог не будет выведена даже пустая строка.
Дай работающий пример. Чет у меня такое чувство, что там указатель как-то криво хранится...
чуть позже будет.
кстати на:
ResultStruct.used = true;
реакция идет корректная, т.е. пилот получается все-таки видит структуру с результатом...
а почему он должен ее не видеть?
tResultStruct = packed record // Заполняется плагином. Память под строку выделяется и освобождается плагином.
used : boolean; // Используется ли эта структура при возврате значения. = false
RLength : Cardinal; // Размер данных. ТИП НЕ МЕНЯЮ = 0
RArray : Pchar; // Указатель на возвращаемую строку. = ''
Reserved1 : Cardinal;
Reserved2 : Cardinal;
Reserved3 : Int64;
Reserved4 : Int64;
end;
z : tResultStruct; //глобально
//заполним данные
z.RArray := 'f';
z.RLength := Length(z.RArray);
вызов
ParamStruct := AdressPS;
//адрес структуры приведем к инт
ParamStruct^.Reserved := Integer(@z);
z.used := True;
// return value not analized while, may be later
Result := true;
21:13:07 4 (autosaved_4.txt, 1): f
Потому что не видит результат, как следствие у нас возникли вопросы видит ли он вообще структуру. Вопрос решен. Точнее причина найдена, решение ищу... Bool 4 байта... byte, char, char[1] тоже по 4 байта. Отсюда все и съезжает.
Решение(вроде только под MSVS):
#pragma pack(push, 1)
struct tResultStruct // Заполняется плагином. Память под строку выделяется и освобождается плагином.
{
bool used; // Используется ли эта структура при возврате значения. = false
unsigned int RLength; // Размер данных.
char *RArray; // Указатель на возвращаемую строку.
unsigned int Reserved1;
unsigned int Reserved2;
unsigned __int64 Reserved3;
unsigned __int64 Reserved4;
};
#pragma pack(pop)
Доброго времени суток, а не кто случаем не сталкивался и нету ли готового решения плагина/дополнения, я хочу выложить свой скрипт, но не хочу что бы код его был открыт. Для этого нужен плагин для шифрования/дешифровки скрипта.
Это не решается плагином.
Нет. Нету.
И? А как ты пилот заставишь потом понимать эти шифрованные скрипты?
Что мешает один раз кому-то купить и раздать всем? Да и не факт, что вообще покупать придется. Грош цена такому шифрованию.
------
А я предлагал дать возможность дергать функции пилота из плагина. Тут и проблема бы с долгожданной компиляцией решилась. И скоростью работы, кстати.
К тому же подобное шифрование никак не скрывает код скрипта. По большому счету с тем же успехом можно создать запароленный архив - в текущей ситуации разницы никакой.
да
В планы реализации входит.
Туда много чего входит, выходит оттуда мало
Вообще, всё из перечисленного, но подозреваю, что апи реальней увидеть в обозримом будущем. Тут многое от ДаркМастера зависит
Мне бы еще понять причем тут я и, что от меня хотят...
Темку солью с разработкой плагинов - не теряйте.
Кнайта пинать.
Скрипт :
set logging clear
set logging mode fulltime
set logging begin
set $a FilesAPI.OpenFile (*z.zip* *Read*)
msg $a //вывод хендла файла(первый проход нормально выводит, второй выводит %b)
set %b FilesAPI.ReadArrayOfByte (* $a * *1000*) //в %b будет массив байт
set $a FilesAPI.CloseFile (* $a *)
msg $a //вывод результата закрытия файла(вместо 1 или 0 выводит %b)
//первый прогон скрипта выдаст 1000 элементов, т.е. сколько и указано было при чтении
//второй выдаст на 1 элемент меньше и первый элемент некорректный
for #n 1 size(%b[1])
set logging %b[1 #n]
end_for
set logging end
set logging size(%b[1])
end_script
в 2.35 тоже самое.
Где брать 2.33 и другие старые версии?
вообще на сайте они есть. ну и я залить могу.
в старых версиях нет. упоминание есть, а скачать нельзя.
Все прекрасно качается с сайта. Обновил репозиторий в теме полезных советов из личного склада. 2.36 (базовую, не .1 .2) скачал с сайта и прилепил туда же.
ссылку сайта тогда можно?
http://uopilot.uokit.com/
тыкаем old version тыкам на номер версии.
33 недоступен. как и многие другие
Хм... Странно.
https://redmine.uokit.com/projects/uopilot/issues )
Чего? написать репорт?
Чиркани =) Ну или я чиркану...
версии все нужные в полезных советах есть? могу еще что-нибудь залить)
В советах только ссылка на самую новую. Истории не увидел. Она где то в постах, а не в шапке?
Добавил несколько ссылок на старые версии на хомпейдже. Русская и английская версии странички слегка отличаются в этом плане. 2,33 отключена умышленно, зачем - не помню. Включать не стал.
в чем прикол? и где теперь его брать?
скорее всего проблема из-за гугла с его паническими атаками на вирусню. Взять можно в соседней теме "полезные советы". Я бы рекомендовал запаковать пилот в запароленный архив и все-таки выложить.
Приветствую, есть некоторые вопросы по плагинам:
- как передать в плагин массив?
пример скрипта:
set #n 20
set $s "foo bar"
init_arr %arr 10 20 30
log UOPilotPlugin.Function1(#n, $s, %arr)
stop_script
void UOPILOT_CALL Function1(tParamStruct* ParamStruct)
{
sprintf_s(ParamStruct->Result,
"%s" "%u" "%s" "%u" "%s" "%s" "%s" "%s",
"Handle ", (size_t) ParamStruct->WindowHandle,
"; PID ", (size_t) ParamStruct->WindowPID,
"; Parameter string ", ParamStruct->ParamString,
"; Parameter string original ", ParamStruct->ParamStringOrig
);
}
--lua
log("clear")
local n = 20
local s = "foo bar"
local arr = {10,20,30}
log(UOPilotPlugin.Function1(n, s, arr))
stop_script()
Массив вроде можно передать как %a[1]
--lua
local w = findwindow("BlueStacks") -- ищем окно BlueStacks
if (w[1]) then -- если найдено
log (w[1][1])
local childhandle = getwindow(w[1][1], "Child")
log (childhandle)
end
get ("windowpos workwindow #x #y #w #h")
x, y, w, h = "#x", "#y", "#w", "#h"
log (x, y, w, h)
build 12
Починил 'get windowpos' в Lua. Теперь работает как функция 'x, y, width, height, errorcode = windowpos (<handle>)'.
// пока не опубликовано.
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)