Как отправить команду в QUIK из приложения C#

Автор записи: Дмитрий (Admin)

Qlua-csharp-connector-dllВ статье "Обмен данными между DLL (C/C++) и приложением C#" показан простой пример отправки сообщений из DLL в приложение C#, а QUIK(Lua) просто запускает и останавливает эту отправку. Для отправки команд из приложения C# в QUIK лучше использовать примерно следующую конструкцию:

QLua-функция main()
-- с периодичность в 1 миллисекунду проверяет не пришла ли команда из C#
function main()
   while IsRun do
      -- Если функция вернула не пустую строку
      local CommandStr = tostring(QluaCSharpConnector.GetCommand());
      if CommandStr ~= "" then
        -- здесь будет Ваш код обработки команды
      end;
      sleep(1);
   end;
end;
DLL-функция (C/C++) GetCommand()
(Если Вы не знаете как создавать библиотеки DLL, которые можно использовать в скриптах QLua(Lua), ознакомьтесь, пожалуйста, с данной статьей).

// Имя для выделенной памяти
TCHAR Name[] = TEXT("QUIKCommand");
// Создаст, или подключится к уже созданной памяти с таким именем
HANDLE hFileMapQUIKCommand= CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, Name);
 
static int forLua_GetCommand(lua_State *L)
{
   //Если указатель на память получен
   if (hFileMapQUIKCommand)
   {
      //Получает доступ к байтам памяти
      PBYTE pb = (PBYTE)(MapViewOfFile(hFileMapQUIKCommand, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 256));
 
      //Если доступ к байтам памяти получен
      if (pb != NULL)
      {
         //Если память чиста
         if (pb[0] == 0)
         {
            //Записывает в Lua-стек пустую строку
            lua_pushstring(L, "");
         }
         else //Если в памяти есть команда
         {
            //Записывает в Lua-стек полученную команду
            lua_pushstring(L, (char*)(pb));
            //Стирает запись, чтобы повторно не выполнить команду
	    for (int i = 0; i < 256; i++)pb[i] = '\0';
         }
 
         //Закрывает представление
         UnmapViewOfFile(pb);
      }
      else lua_pushstring(L, "");//Если доступ к байтам памяти не был получен, записывает в Lua-стек пустую строку
   }
   else //Указатель на память не был получен
   {
      //Записывает в Lua-стек пустую строку
      lua_pushstring(L, "");
   }
   //Функция возвращает записанное значение из Lua-стека (пустую строку, или полученную команду)
   return(1);
}
Код C#

// Создаст, или подключится к уже созданной памяти с таким именем
public MemoryMappedFile MemoryQUIKCommand;
// Создает поток для чтения
StreamReader SR_QUIKCommand;
// Создает поток для записи
StreamWriter SW_QUIKCommand;

//выделяет именованную память размером 256 байт для отправки КОМАНД в QUIK, создает потоки чтения/записи
MemoryQUIKCommand = MemoryMappedFile.CreateOrOpen("QUIKCommand", 256, MemoryMappedFileAccess.ReadWrite);
SR_QUIKCommand = new StreamReader(MemoryQUIKCommand.CreateViewStream(), System.Text.Encoding.Default);
SW_QUIKCommand = new StreamWriter(MemoryQUIKCommand.CreateViewStream(), System.Text.Encoding.Default);

//Функция отправки команды в QUIK ( вызов: SetQUIKCommandData("Ваша команда"); ), или очистки памяти, при вызове без параметров ( вызов: SetQUIKCommandData(); )
private void SetQUIKCommandData(string Data = "")
{
   //Если нужно отправить команду
   if (Data != "")
   {
      //Дополняет строку команды "нулевыми байтами" до нужной длины
      for (int i = Data.Length; i < 256; i++) Data += "\0";
   }
   else //Если нужно очистить память
   {
      //Заполняет строку для записи "нулевыми байтами"
      for (int i = 0; i < 256; i++) Data += "\0";
   }
   //Встает в начало
   SW_QUIKCommand.BaseStream.Seek(0, SeekOrigin.Begin);
   //Записывает строку
   SW_QUIKCommand.Write(Data);
   //Сохраняет изменения в памяти
   SW_QUIKCommand.Flush();
}
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!