Функция Windows API WriteFile() приводит к краху МТ4. - страница 2

 

Сделал окончательный вариант универсальной функции для неограниченных файловых операций для MQL4, но он не работает :-(

В какой момент перестал работать не уследил. Возврат в прежнее состояние ни чего не дал. Ни запись, ни чтение не происходят. Функции записи и чтения возвращают FALSE. Функция "_lwrite()" работает. Оставил её закоментированной. С ней запись происходит.

//+--------------------------------------------------------------+
//|               ZH_File_Functions_Full_String_Value_Lib 0-81006.mq4|
//|               Copyright © Zhunko                                 |
//|06.10.2008        ZHUNKO vadim@zhunko.ru                          |
//+--------------------------------------------------------------+
//|            Операции для бинарного файла строковых данных.               |
//+--------------------------------------------------------------+
#property copyright "Copyright © 2008 Zhunko"
#property link      "vadim@zhunko.ru"
#property library
// Импортируемые функции.
#import "kernel32.dll"
 bool CloseHandle (int hObject);
 bool ReadFile (int& hFile, string& lpBuffer, int& nNumberOfBytesToRead, int& lpNumberOfBytesRead[], int lpOverlapped);
 bool WriteFile (int& hFile, string& lpBuffer, int& nNumberOfBytesToWrite, int& lpNumberOfBytesWritten[], int lpOverlapped);
 int  CreateFileA (string lpFileName, int dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);
 int  SetFilePointer (int hFile, int lDistanceToMove, int lpDistanceToMoveHigh, int dwMoveMethod);
#import
// Объявленные константы.
#define FILE_CREATE_                 0
#define FILE_WRITE_                  1
#define FILE_READ_                   2
#define GENERIC_WRITE                0x40000000
#define GENERIC_READ                  0x80000000
#define FILE_SHARE_READ              0x00000001
#define FILE_SHARE_WRITE             0x00000002
#define FILE_SHARE_DELETE            0x00000004 
#define CREATE_NEW                   1
#define CREATE_ALWAYS                2
#define OPEN_EXISTING                3
#define OPEN_ALWAYS                  4
#define TRUNCATE_EXISTING             5
#define FILE_ATTRIBUTE_NORMAL        0x80
//----
//#include <WinKernel32.mqh> // Заголовочный файл библиотеки "kernel32.dll" функций API Windows XP.
//==============================================================================================================================
// Функция "Операции для бинарного файла строковых данных".===========================================================================
// Возвpащает число записанных или прочитанных байт. В случае неуспешного завеpшения функция возвращает "-1".
int FileOperationsStringValue (string& PathName, // Название файла.
                               string& Value,    // Переменная для записи или чтения.
                               int&    ModeCWR,  // Тип производимых действий с файлом: 0 - FILE_CREATE_  создать или переписать файл;
                                                 //                                     1 - FILE_WRITE_   дописать файл;
                                                 //                                     2 - FILE_READ_    читать файл.
                               int&    Size,     // Длина записываемой строки.
                               int&    Offset,   // Смещение в байтах файлового указателя.
                               int&    Origin)   // Начальное положение файлового указателя: SEEK_CUR - от текущего положения,
                                                 //                                          SEEK_SET - от начала,
                                                 //                                          SEEK_END - от конца файла).
 {
  int Handle; // Системный дескриптор файла.
  //----
  int Return[1]; // Буфер для возврата числа записанных или прочитанных байт.
  //----
  switch (ModeCWR)
   {
    case 0: {Handle = CreateFileA (PathName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); break;} // Создаём файл.
    case 1: {Handle = CreateFileA (PathName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); break;} // Дописываем файл.
    case 2: {Handle = CreateFileA (PathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); break;}   // Читаем файл.
    default: Print ("Ошибка в функции \"FileOperationsStringValue()\". Тип производимых действий с файлом с путём \"", PathName, "\" выбран не верно. ModeCWR = ", ModeCWR); return (-1);
   }
  if (Handle == -1) // Если файл не открыт.
   {
    Print ("Ошибка в функции \"FileOperationsStringValue()\". Файл с путём \"", PathName, "\" не открыт.");
    return (-1);
   }
  if (SetFilePointer (Handle, Offset, NULL, Origin) == -1) // Если файл открыт, сдвигаем файловый указатель, куда требуется.
   {
    Print ("Ошибка в функции \"FileOperationsStringValue()\". Файловый указатель файла с путём \"", PathName, "\" не смещён.");
    if (CloseHandle (Handle) == false) Print ("Ошибка в функции \"FileOperationsStringValue()\". Файл с путём \"", PathName, "\" не закрыт.");
    return (-1);
   }
  switch (ModeCWR)
   {
    case 0: // Записываем или дописываем в файл входное значение.
    case 1: {if (WriteFile (Handle, Value, Size, Return, NULL) == false) Print ("Ошибка в функции \"FileOperationsStringValue()\". Значение в файл с путём \"", PathName, "\" не записано."); break;}
    case 2: {if (ReadFile (Handle, Value, Size, Return, NULL) == false) Print ("Ошибка в функции \"FileOperationsStringValue()\". Значение в файл с путём \"", PathName, "\" не записано."); break;} // Читаем из файла значение.
   }
//  Return[0] = _lwrite (Handle, Value, Size);
//  if (Return[0] == -1) Print ("Ошибка в функции \"CreateFileStringValue()\". Значение в файл с путём \"", PathName, "\" не записано.");
  if (CloseHandle (Handle) == false) // Закрываем файл.
   {
    Print ("Ошибка в функции \"FileOperationsStringValue()\". Файл с путём \"", PathName, "\" не закрыт.");
    return (-1);
   }
  return (Return[0]);
 }
Можно сделать 6 таких функций с разным вторым параметром. Можно менять у него тип и делать его массивом. Это будет хорошая замена встроенным файловым функциям.
 
Zhunko >>:

Сделал окончательный вариант универсальной функции для неограниченных файловых операций для MQL4, но он не работает :-(

В какой момент перестал работать не уследил. Возврат в прежнее состояние ни чего не дал. Ни запись, ни чтение не происходят. 

Вадим, у тебя некорректно объявлены системные функции чтения и записи.

Вместо 

 bool ReadFile (int& hFile, string& lpBuffer, int& nNumberOfBytesToRead, int& lpNumberOfBytesRead[], int lpOverlapped);
 bool WriteFile (int& hFile, string& lpBuffer, int& nNumberOfBytesToWrite, int& lpNumberOfBytesWritten[], int lpOverlapped);

необходимо записать следующим образом

 bool ReadFile (int hFile, string lpBuffer, int nNumberOfBytesToRead, int& lpNumberOfBytesRead[], int lpOverlapped);
 bool WriteFile (int hFile, string lpBuffer, int nNumberOfBytesToWrite, int& lpNumberOfBytesWritten[], int lpOverlapped);

Т.е. ряд параметров функции (hFile, nNumberOfBytesToRead и т.д.) передаются по значению, а не по ссылке.

Вообще без явной необходимости не рекомендую передавать параметры системных функций по ссылке - это может стать источником 

трудно уловимых ошибок. 

 

УФ! Спасибо! Заработало! Забыл ссылки убрать и вообще не придавал этому значения.

Но!!! Всё равно дописыват криво.

 

Разобрался! Забыл о параметре длины записываемой строки.

Ильнур ещё раз спасибо! Всё работает!

 

Вадим, выложите, пожалуйста, окончательный вариант функции. Скачаем и в кладовочку положим. Такая вещь в хозяйстве пригодится.

Или в CodeBase ee, родимую.

 
granit77 писал(а) >>

Вадим, выложите, пожалуйста, окончательный вариант функции. Скачаем и в кладовочку положим. Такая вещь в хозяйстве пригодится.

Или в CodeBase ee, родимую.

присоединяюсь

 

Вообщем-то она здесь выложена. Она на самом верху этой страницы. Там надо только ссылки убрать, там где Ильнур показал.

Библиотеку выложу, но не скоро. Может через неделю. Здесь только одна функция выложена, а будет их 6. Для разных типов данных. Ещё будут вспомогательные функции. Тоже не мало.

Благодаря Ильнуру, который показал, как работать с системными ошибками, все функции будут возвращать ошибки от Windows.