Brumo |
Отправлено: 28 Февраля, 2021 - 15:00:09
|
Наблюдатель
Покинул форум
Сообщений всего: 28
Дата рег-ции: Февр. 2020
Репутация: 7
|
Пример обмена данными между приложениями(Kibor >> Python, Kibor >> Kibor) с помощью Shared memory
Грубо говоря обмен данными происходит через общую(разделяемую) память в виртуальном адресном пространстве
Сначала запустить "Сервер", затем "Клиент"(Python или Kibor, можно оба). Нажать старт на "Сервере"
Cервер Kibor, "записывает" в виртуальную память данные (Отобразить)
CODE:
#define FORMAT_MESSAGE_FROM_SYSTEM 4096
#define FORMAT_MESSAGE_IGNORE_INSERTS 512
#define PAGE_READWRITE 4
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define FALSE 0
#define NULL 0
#define INVALID_HANDLE_VALUE -1
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll" );
external(INT, "FormatMessage", "FormatMessageA", "kernel32.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll" );
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll" );
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll" );
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll" );
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll" );
external(INT, "GetLastError", "GetLastError", "Kernel32.dll" );
string mappingname = "EventName";//Имя "отображаемого" объекта.
new char Buf[256];
string send_data = "Message from first process.";
strcpy(#Buf[0], send_data);
int hFileMapping;
int lpFileMap;
//Создание именованного объекта файлового отображения, возвращает дескриптор объекта.
hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, mappingname);
if(hFileMapping==0)
{
error_text("Ошибка CreateFileMapping: ");
goto end;
}
//Получение начального адреса(указателя) на отображенную область памяти.
lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==0)
{
error_text("Ошибка MapViewOfFile: ");
goto end;
}
send();
messagebox("Старт");
delete Buf;
new char Buf[256];
//Цикл "передает" данные ~100 раз за секунду
int b=0;
for (int a=-1; a<100; a++)
{
sleep(10);
send_data = format(b);
strcpy(#Buf[0], send_data);
send();
b++;
}
messagebox("Передача окончена");
//Копирование содержимого блока памяти "address(#Buf[0])" в целевой блок памяти "lpFileMap"
function send()
{
RtlMoveMemory(lpFileMap, address(#Buf[0]), sizearray(Buf));
}
function error_text(string er_text)
{
int error=GetLastError();
char message[999];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, address(#message[0]), sizearray(message), 0);
messagebox(er_text+format(#message[0])+"("+ format(error)+")");
}
end:
/////////////////////////////////////////////////////////////////
if(UnmapViewOfFile(lpFileMap)!=1)//Отменяет отображение.
{
error_text("Ошибка UnmapViewOfFile: ");
}
if(CloseHandle(hFileMapping)!=1)//Закрывает дескриптор созданного объекта.
{
error_text("Ошибка CloseHandle: ");
}
//////////////////////////////////////////////////////////////////
Kлиент Python, "читает" с виртуальной памяти данные(ссылка) (Отобразить)(для просмотра ссылки Вам необходимо авторизоваться)
P.s. (Отобразить)
Параметр dwMaximumSizeHigh менять не стоит!, 0 - для объектов отображения до 4.294 GB:
Цитата:
HANDLE CreateFileMappingA(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh, //Старшее двойное слово (DWORD) максимального размера объекта "проецируемый файл".
DWORD dwMaximumSizeLow,
LPCSTR lpName
);
(Добавление)
Клиент Kibor (Отобразить)
CODE:
#define FORMAT_MESSAGE_FROM_SYSTEM 4096
#define FORMAT_MESSAGE_IGNORE_INSERTS 512
#define PAGE_READWRITE 4
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define FALSE 0
#define NULL 0
#define INVALID_HANDLE_VALUE -1
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll" );
external(INT, "FormatMessage", "FormatMessageA", "kernel32.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll" );
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll" );
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll" );
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll" );
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll" );
external(INT, "GetLastError", "GetLastError", "Kernel32.dll" );
string mappingname = "EventName";//Имя "отображаемого" объекта.
char Buf[256];
string get_data = "Message from first process.";
int hFileMapping2;
int lpFileMap2;
//Открытие именованного объекта файлового отображения, возвращает дескриптор объекта.
hFileMapping2 = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mappingname);
if(hFileMapping2==0)
{
error_text("Ошибка OpenFileMapping: ");
goto end;
}
//Получение начального адреса(указателя) на отображенную область памяти.
lpFileMap2 = MapViewOfFile(hFileMapping2, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap2==0)
{
error_text("Ошибка MapViewOfFile: ");
goto end;
}
get();
textout(0, 500, 500, format(#Buf[0]), 0);
while(format(#Buf[0])==get_data)
{
sleep(1);
get();
textout(0, 500, 500, format(#Buf[0]), 0);
}
resettextout(1);
looptime(1500)
{
sleep(10);
get();
textout(1, 500, 500, format(#Buf[0]), 0);
if(format(#Buf[0])=="100"){break;}
}
messagebox("Прием окончен");
//Копирование содержимого блока памяти "lpFileMap" в целевой блок памяти "address(#Buf[0])"
function get()
{
RtlMoveMemory(address(#Buf[0]), lpFileMap2, 256);
}
function error_text(string er_text)
{
int error=GetLastError();
char message[999];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, address(#message[0]), sizearray(message), 0);
messagebox(er_text+format(#message[0])+"("+ format(error)+")");
}
end:
/////////////////////////////////////////////////////////////////
if(UnmapViewOfFile(lpFileMap2)!=1)//Отменяет отображение.
{
error_text("Ошибка UnmapViewOfFile: ");
}
if(CloseHandle(hFileMapping2)!=1)//Закрывает дескриптор созданного объекта.
{
error_text("Ошибка CloseHandle: ");
}
//////////////////////////////////////////////////////////////////
|
|
|
Zireael |
Отправлено: 18 Марта, 2023 - 02:34:30
|
Эксперт
Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Пример как из одного exe передать 2 числа другому и получить в ответ сумму этих чисел.
Скрипт, передающий данные (Отобразить)CODE:#define PAGE_READWRITE 0x04
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define INVALID_HANDLE_VALUE -1
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SizeBuf, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error CreateFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
string message = "123 45"; // эту строку передаём другому exe
strcpy(#Buf[0], message);
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
while(format(#Buf[0]) == message) // ждём когда строка изменится
{
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf);
sleep(100);
}
messagebox("Result = " + format(#Buf[0]));
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);
Скрипт, принимающий данные и возвращающий ответ (Отобразить)CODE:#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error OpenFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf); // получить переданную строку
string str = format(#Buf[0]);
messagebox("Получена строка: "+"^r^n"+str);
// разбор переданной строки на параметры
int result = 0;
string param[9];
if(regexsearch(sizearray(param), #param[0], str, "\d+")>=2) // найти в строке 2 числа
{
result = formatsn(param[0]) + formatsn(param[1]);
strcpy(#Buf[0], format(result));
}
else strcpy(#Buf[0], "Передано меньше двух чисел");
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping); (Отредактировано автором: 18 Марта, 2023 - 02:46:06) |
|
|
Zireael |
Отправлено: 18 Марта, 2023 - 22:10:59
|
Эксперт
Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Пример как из одного exe передать 2 числа другому и получить в ответ сумму этих чисел.
Используется семафор. Первый exe ожидает когда второй exe даст сигнал что нужные действия выполнены.
Скрипт, передающий данные (Отобразить)CODE:#define PAGE_READWRITE 0x04
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define INVALID_HANDLE_VALUE -1
#define WAIT_TIMEOUT 0x00000102
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SizeBuf, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error CreateFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
string message = "123 45"; // это строку передаём другому exe
strcpy(#Buf[0], message);
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
int h = CreateSemaphore(0, 0, 1, "MySemaphore");
if(h!=NULL)
{
// ждём когда второй exe даст сигнал, не более 10 сек
if(WaitForSingleObject(h, 10000)==WAIT_TIMEOUT)messagebox("Время вышло");
CloseHandle(h);
}
else messagebox("Не удалось создать семафор");
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf);
messagebox("Result = " + format(#Buf[0]));
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);
Скрипт, принимающий данные и возвращающий ответ (Отобразить)CODE:#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define SEMAPHORE_MODIFY_STATE 0x0002
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error OpenFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf); // получить переданную строку
string str = format(#Buf[0]);
//messagebox("Получена строка: "+"^r^n"+str);
// разбор переданной строки на параметры
int result = 0;
string param[9];
if(regexsearch(sizearray(param), #param[0], str, "\d+")>=2) // найти в строке 2 числа
{
result = formatsn(param[0]) + formatsn(param[1]);
strcpy(#Buf[0], format(result));
}
else strcpy(#Buf[0], "Передано меньше двух чисел");
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
int h = OpenSemaphore(SEMAPHORE_MODIFY_STATE, 0, "MySemaphore");
if(h!=NULL)
{
ReleaseSemaphore(h, 1, NULL); // увеличить счётчик семафора на 1
CloseHandle(h);
}
else messagebox("Не удалось создать семафор");
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);
|
|
|
Redear |
Отправлено: 21 Марта, 2023 - 13:36:12
|
Мастер
Покинул форум
Сообщений всего: 202
Дата рег-ции: Июль 2022
Репутация: 0
|
Zireael пишет: Пример как из одного exe передать 2 числа другому и получить в ответ сумму этих чисел.
Используется семафор. Первый exe ожидает когда второй exe даст сигнал что нужные действия выполнены.
Скрипт, передающий данные (Отобразить)CODE:#define PAGE_READWRITE 0x04
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define INVALID_HANDLE_VALUE -1
#define WAIT_TIMEOUT 0x00000102
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SizeBuf, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error CreateFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
string message = "123 45"; // это строку передаём другому exe
strcpy(#Buf[0], message);
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
int h = CreateSemaphore(0, 0, 1, "MySemaphore");
if(h!=NULL)
{
// ждём когда второй exe даст сигнал, не более 10 сек
if(WaitForSingleObject(h, 10000)==WAIT_TIMEOUT)messagebox("Время вышло");
CloseHandle(h);
}
else messagebox("Не удалось создать семафор");
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf);
messagebox("Result = " + format(#Buf[0]));
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);
Скрипт, принимающий данные и возвращающий ответ (Отобразить)CODE:#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define SEMAPHORE_MODIFY_STATE 0x0002
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MappingName);
if(hFileMapping==NULL)
{
messagebox("Error OpenFileMapping");
goto end;
}
int lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap==NULL)
{
messagebox("Error MapViewOfFile");
goto end;
}
RtlMoveMemory(address(#Buf[0]), lpFileMap, SizeBuf); // получить переданную строку
string str = format(#Buf[0]);
//messagebox("Получена строка: "+"^r^n"+str);
// разбор переданной строки на параметры
int result = 0;
string param[9];
if(regexsearch(sizearray(param), #param[0], str, "\d+")>=2) // найти в строке 2 числа
{
result = formatsn(param[0]) + formatsn(param[1]);
strcpy(#Buf[0], format(result));
}
else strcpy(#Buf[0], "Передано меньше двух чисел");
RtlMoveMemory(lpFileMap, address(#Buf[0]), SizeBuf);
int h = OpenSemaphore(SEMAPHORE_MODIFY_STATE, 0, "MySemaphore");
if(h!=NULL)
{
ReleaseSemaphore(h, 1, NULL); // увеличить счётчик семафора на 1
CloseHandle(h);
}
else messagebox("Не удалось создать семафор");
end:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);
большое спасибо, это то что нужно.
возник вопрос, как поставить программу приемник на ожидание получения сообщения, чтобы это было максимально оперативно.
читать память в цикле с задержкой 1 мс, не думаю, что самый рациональный метод. спасибо |
|
|
Zireael |
Отправлено: 21 Марта, 2023 - 18:34:33
|
Эксперт
Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Цитата: как поставить программу приемник на ожидание получения сообщения
Также как и ожидание ответа через WaitForSingleObject.
Скрипт, передающий данные (Отобразить)CODE:#define PAGE_READWRITE 0x04
#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define INVALID_HANDLE_VALUE -1
#define WAIT_TIMEOUT 0x00000102
#define SEMAPHORE_MODIFY_STATE 0x0002
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[9999];
int SizeBuf = sizearray(Buf);
int FileMapping, FileMap;
if(CreateMap()<0)goto end; // создать общий файл
messagebox("Запустите скрипт принимающий данные.^r^nПосле этого можно продолжить.");
// для примера отправка данных в цикле
for(int i=0; i<5; i++)
{
WriteMemory(format(i) + " 100"); // отправляем текст другому exe, который вернёт сумму
WaitResponce(); // ждём ответ
string Text = ReadMemory(); // читаем ответ
messagebox("Result = " + Text);
}
//WriteMemory("Exit"); //отправить этот текст если нужно закрыть exe принимающий данные
ReleaseResource(); // освобождаем ресурсы, можно не вызывать если функция CreateMap вызывается 1 раз
function CreateMap()
{
FileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SizeBuf, MappingName);
if(FileMapping==NULL)
{
messagebox("Error CreateFileMapping");
return -1;
}
FileMap = MapViewOfFile(FileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(FileMap==NULL)
{
messagebox("Error MapViewOfFile");
return -2;
}
return 1;
}
function WriteMemory(string Message)
{
strcpy(#Buf[0], Message);
RtlMoveMemory(FileMap, address(#Buf[0]), SizeBuf);
// сообщаем что нужные действия выполнены
int Semaphore = OpenSemaphore(SEMAPHORE_MODIFY_STATE, 0, "Semaphore");
if(Semaphore==NULL)
{
messagebox("Не удалось открыть семафор");
goto global end;
}
else
{
ReleaseSemaphore(Semaphore, 1, NULL);
CloseHandle(Semaphore);
}
}
function ReadMemory()
{
RtlMoveMemory(address(#Buf[0]), FileMap, SizeBuf);
return format(#Buf[0]);
}
function WaitResponce()
{
// ждём когда exe даст сигнал, не более 10 сек
int Semaphore = CreateSemaphore(NULL, 0, 1, "Semaphore");
if(Semaphore==NULL)
{
messagebox("Не удалось создать семафор");
goto global end;
}
else
{
if(WaitForSingleObject(Semaphore, 10000)==WAIT_TIMEOUT) messagebox("Время вышло");
CloseHandle(Semaphore);
}
}
function ReleaseResource()
{
if(FileMap != NULL) UnmapViewOfFile(FileMap);
if(FileMapping != NULL) CloseHandle(FileMapping);
}
end:
ReleaseResource();
Скрипт, принимающий данные и возвращающий ответ (Отобразить)CODE:#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define WAIT_TIMEOUT 0x00000102
#define SEMAPHORE_MODIFY_STATE 0x0002
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int SizeBuf = sizearray(Buf);
int FileMapping, FileMap;
if(OpenMap()<0)goto end;
loop()
{
WaitRequest(); // ждать когда придут данные
string Text = ReadMemory(); // прочитать данные
//messagebox("Получена строка:^r^n"+Text);
if(Text=="Exit") close(); // закрыть программу если пришло Exit
// разбор переданной строки на параметры
int result = 0;
string param[9];
if(regexsearch(sizearray(param), #param[0], Text, "\d+")>=2) // найти в строке 2 числа
{
result = formatsn(param[0]) + formatsn(param[1]);
strcpy(#Buf[0], format(result));
}
else strcpy(#Buf[0], "Передано меньше двух чисел");
WriteMemory(format(result)); // записать ответ
}
function OpenMap()
{
FileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MappingName);
if(FileMapping==NULL)
{
messagebox("Error CreateFileMapping");
return -1;
}
FileMap = MapViewOfFile(FileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(FileMap==NULL)
{
messagebox("Error MapViewOfFile");
return -2;
}
return 1;
}
function WriteMemory(string Message)
{
strcpy(#Buf[0], Message);
RtlMoveMemory(FileMap, address(#Buf[0]), SizeBuf);
// сообщаем что нужные действия выполнены
int Semaphore = OpenSemaphore(SEMAPHORE_MODIFY_STATE, 0, "Semaphore");
if(Semaphore==NULL)messagebox("Не удалось открыть семафор");
else
{
ReleaseSemaphore(Semaphore, 1, NULL);
CloseHandle(Semaphore);
}
}
function ReadMemory()
{
RtlMoveMemory(address(#Buf[0]), FileMap, SizeBuf);
return format(#Buf[0]);
}
function WaitRequest()
{
// ждём когда exe даст сигнал
int Semaphore = CreateSemaphore(NULL, 0, 1, "Semaphore");
if(Semaphore==NULL)messagebox("Не удалось открыть семафор");
else
{
if(WaitForSingleObject(Semaphore, 999999999)==WAIT_TIMEOUT) messagebox("Время вышло");
CloseHandle(Semaphore);
}
}
function ReleaseResource()
{
if(FileMap != NULL) UnmapViewOfFile(FileMap);
if(FileMapping != NULL) CloseHandle(FileMapping);
}
end:;
ReleaseResource(); |
|
|
Redear |
Отправлено: 21 Марта, 2023 - 18:59:31
|
Мастер
Покинул форум
Сообщений всего: 202
Дата рег-ции: Июль 2022
Репутация: 0
|
большое спасибо, крепкого вам здоровья,
небольшой вопрос по синтаксису,
не нарушает ли синтаксис, если создать отдельную функцию которая будет загружать функции из библиотек. или загрузка должна быть в рамках основной программы.
CODE:
например
function load ()
{
..
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "CreateFileMapping", "CreateFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
...
|
|
|
Zireael |
Отправлено: 30 Апреля, 2023 - 15:45:34
|
Эксперт
Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Пример использования кибор для распознавания текста из другой программы, в данном случае консольное приложение C#.
В скрипте кибор указать путь к базе символов в unpack и блоке ресурсов. Собрать скрипт в exe с включёнными галками: Запускать скрипт с запуском exe и Упаковать файлы с блока ресурсов.
В приложении C# указать координаты для распознавания текста и путь к exe кибор, который будет распознавать текст.
Скрипт кибор (Отобразить)CODE:#define FILE_MAP_READ 4
#define FILE_MAP_WRITE 2
#define NULL 0
#define WAIT_TIMEOUT 0x00000102
#define SEMAPHORE_MODIFY_STATE 0x0002
external(INT, "CreateSemaphore", "CreateSemaphoreA", "Kernel32.dll");
external(INT, "OpenSemaphore", "OpenSemaphoreA", "Kernel32.dll");
external(INT, "ReleaseSemaphore", "ReleaseSemaphore", "Kernel32.dll");
external(VOID, "RtlMoveMemory", "RtlMoveMemory", "Ntdll.dll");
external(INT, "OpenFileMapping", "OpenFileMappingA", "Kernel32.dll");
external(INT, "MapViewOfFile", "MapViewOfFile", "Kernel32.dll");
external(INT, "CloseHandle", "CloseHandle", "Kernel32.dll");
external(INT, "UnmapViewOfFile", "UnmapViewOfFile", "Kernel32.dll");
external(INT, "WaitForSingleObject", "WaitForSingleObject", "Kernel32.dll");
string MappingName = "MyFileName";
char Buf[999];
int FileMapping, FileMap;
unpack("D:\Kibor2\basetext.sib", pathfolder()+"basetext.sib", 0);
loadsymbolbase (pathfolder()+"basetext.sib");
if(OpenMap()<0)goto end; // открыть общий файл для чтения/записи
WriteMemory("Start"); // ответить основной программе что кибор готов получить данные
loop()
{
WaitRequest(); // ждём когда придут данные
string Text = ReadMemory(); // прочитать данные
//messagebox("Получен текст^r^n"+Text);
if(Text=="Close")close(); // закрыть кибор если получен текст Close
//разбор строки
string num[4];
int coord[4];
if(regexsearch(4, #num[0], Text, "\d+")==4) // найти 4 числа
{
coord[0] = formatsn(num[0]);
coord[1] = formatsn(num[1]);
coord[2] = formatsn(num[2]);
coord[3] = formatsn(num[3]);
readtext (RU | EN | MARK, #Text, 8, 1, -1, -1, -1, -1, -1, 0, -1, coord[0], coord[1], coord[2], coord[3], -1);
WriteMemory(Text); // передать основной программе распознаный текст
}
else WriteMemory("В переданной строке нет 4 чисел");
}
function OpenMap()
{
FileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, MappingName);
if(FileMapping==NULL)
{
messagebox("Error CreateFileMapping");
return -1;
}
FileMap = MapViewOfFile(FileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if(FileMap==NULL)
{
messagebox("Error MapViewOfFile");
return -2;
}
return 1;
}
function WriteMemory(string Message)
{
string msg = ansitoutf8(Message);
codhex(size(msg), #Buf[0]);
strcpy(#Buf[4], msg);
RtlMoveMemory(FileMap, address(#Buf[0]), size(msg)+4);
// сообщаем что нужные действия выполнены
int Semaphore = OpenSemaphore(SEMAPHORE_MODIFY_STATE, 0, "Semaphore");
if(Semaphore==NULL)messagebox("Не удалось открыть семафор");
else
{
ReleaseSemaphore(Semaphore, 1, NULL);
CloseHandle(Semaphore);
}
}
function ReadMemory()
{
RtlMoveMemory(address(#Buf[0]), FileMap, 4);
int Len = codhexi(#Buf[0], 4);
RtlMoveMemory(address(#Buf[0]), FileMap, Len+4);
return utf8toansi(format(#Buf[4], Len));
}
function WaitRequest()
{
// ждём когда exe даст сигнал
int Semaphore = CreateSemaphore(NULL, 0, 1, "Semaphore");
if(Semaphore==NULL)messagebox("Не удалось открыть семафор");
else
{
if(WaitForSingleObject(Semaphore, 999999999)==WAIT_TIMEOUT) messagebox("Время вышло");
CloseHandle(Semaphore);
}
}
function ReleaseResource()
{
if(FileMap != NULL) UnmapViewOfFile(FileMap);
if(FileMapping != NULL) CloseHandle(FileMapping);
}
end:;
ReleaseResource();
RESOURCE
{
"D:\Kibor2\basetext.sib";
}
Консольное приложение C# (Отобразить)CODE:using System.Diagnostics;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading;
internal class Program
{
static void Main()
{
string message = "236, 139, 298, 160"; // координаты для распознавания текста
MemoryMappedFile sharedMemory = MemoryMappedFile.CreateOrOpen("MyFileName", 999);
string PathToKibor = @"D:\Kibor2\exe\Kibor-exe.exe"; // путь к кибор
if (StartKibor(PathToKibor)) // если кибор запустился
{
Console.WriteLine("Нажать любую клавишу для продолжения");
Console.ReadKey();
SendKiborMessage(message, sharedMemory); // отправить строку с координатами
WaitKiboResponce(); // ждём ответ от кибор
SendKiborMessage("Close", sharedMemory); // отправить текст чтобы кибор закрылся
Console.WriteLine("Нажать любую клавишу для продолжения");
Console.ReadKey();
}
}
static bool WaitKiboResponce()
{
byte[] message; // Массив для сообщения из общей памяти
int size; // Размер сообщения
Semaphore sem = new Semaphore(0, 1, "Semaphore"); // создать семафор
if (sem.WaitOne(5000)) sem.Close(); // ждём 5 секунд ответ от кибор
else
{
Console.WriteLine("Нет сообщения от кибор");
return false;
}
MemoryMappedFile sharedMemory = MemoryMappedFile.OpenExisting("MyFileName"); // открыть общий файл
using (MemoryMappedViewAccessor reader = sharedMemory.CreateViewAccessor(0, 4, MemoryMappedFileAccess.Read))
{
size = reader.ReadInt32(0); // прочитать число int
}
using (MemoryMappedViewAccessor reader = sharedMemory.CreateViewAccessor(4, size, MemoryMappedFileAccess.Read))
{
message = new byte[size];
reader.ReadArray(0, message, 0, size); // прочитать текст
}
string msg = Encoding.UTF8.GetString(message);
Console.WriteLine("Распознаный текст:\t" + msg);
return true;
}
static bool StartKibor(string Path)
{
using (Process process = new Process())
{
process.StartInfo.FileName = Path;
if (!process.Start())
{
Console.WriteLine("Не удалось запустить кибор");
return false;
}
}
Semaphore sem = new Semaphore(0, 1, "Semaphore");
if (sem.WaitOne(5000)) sem.Close();
else
{
Console.WriteLine("Нет сообщения от кибор");
return false;
}
return true;
}
static void SendKiborMessage(string message, MemoryMappedFile sharedMemory)
{
byte[] msg = Encoding.UTF8.GetBytes(message);
using (MemoryMappedViewAccessor writer = sharedMemory.CreateViewAccessor())
{
writer.Write(0, msg.Length);
writer.WriteArray(4, msg, 0, msg.Length);
}
Console.WriteLine("Отправили данные:\t" + Encoding.UTF8.GetString(msg));
try
{
Semaphore sem = Semaphore.OpenExisting("Semaphore");
sem.Release();
sem.Close();
}
catch { Console.WriteLine("Не удалось открыть семафор"); }
}
} |
|
|
|