Ошибка при использовании функции GlobalGetAtomNameA

 

Приветствую!

Возникла потребность передачи данных извне, и моим выбором были атомы - в моём случае это самый удобный. Но функция GlobalGetAtomNameA напрочь отказывается работать, выдаёт мне такие строки в log:

function 'GlobalGetAtomNameA' call from dll 'kernel32.dll' critical error c0000005 at 77276ADE.

Вот код:

#import "kernel32.dll"
  int GlobalAddAtomA(string lpString);
  int GlobalGetAtomNameA(int nAtom, string &lpBuffer, int nSize);
#import

int get_my_atom()
  {
    int i, result = 0;
    string s;
    
    for (i = 0; i < 0xffff; i++)
      {
        GlobalGetAtomNameA(i, s, 255);
        if (StringSubstr(s, 1, 10) == "my_string:")
          {
            result = 1;
            break;
          }
      }

    return(result);
  }

Помогите разобраться, пожалуйста! Версия терминала: 4.00 build 445
 

попробуйте варианты

1. сделать объявление string s="                                         ";

2. передавать string lpBuffer  без адреса

 
#import "kernel32.dll"
  int GlobalAddAtomA(string lpString);
  int GlobalGetAtomNameA(int nAtom, string &lpBuffer, int nSize);
#import

& - лишний. Про буфер Алексей уже сказал.

Билиотеку положил. Может решит Вашу проблему?

 
sergeev, Zhunko огромное спасибо! :) Подразумеваю, что буква M в названии языка означает "Магический". Проблема отчасти была в том, что под переменную s не выделено достаточно памяти. Есть ли возможность это сделать? Чтобы было примерно так: setLength(s, 256);
 
deathNC:

sergeev, Zhunko огромное спасибо! :) Подразумеваю, что буква M в названии языка означает "Магический". Проблема отчасти была в том, что под переменную s не выделено достаточно памяти. Есть ли возможность это сделать? Чтобы было примерно так: setLength(s, 256);

Алексей уже написал, как это сделать!

string s="                                         ";

 В моей библиотеке строки "возвращаются". Заморачиваться с буферами не надо.

 
Алексей уже написал, как это сделать!

Но такое решение называется "сделал на коленке". В принципе, понятно, по-человечески не получится сделать :D

if (GlobalGetAtomNameA(i, s, 128) == 0)
  continue;

А это надо, чтобы удалённые атомы не читались :) (если кому пригодится)
 
 В моей библиотеке строки "возвращаются". Заморачиваться с буферами не надо.
За библиотеку спасибо, как будет время, я в ней покапаюсь :)
 
deathNC:

Но такое решение называется "сделал на коленке". В принципе, понятно, по-человечески не получится сделать :D

Абдула, правила диктую не я а майкрософт.

вам MSDN родным английский языком пишет, что третий параметр в GlobalGetAtomName - размер буфера, куда вы собираетесь принять данные.

и чему же у вас равен этот самый размер буфера?  нулю?

 
и чему же у вас равен этот самый размер буфера?  нулю?

Так и я про что :)

Как мне его задать по человечески? ИМХО, вот это:

s := "                                              ";

самое убогое решение, что я когда либо видел :) но я понял, что по другому никак в mql нельзя.


Абдула, правила диктую не я а майкрософт.

вам MSDN родным английский языком пишет, что третий параметр в GlobalGetAtomName - размер буфера, куда вы собираетесь принять данные.

это я знаю :)
 
самое убогое решение, что я когда либо видел :) но я понял, что по другому никак в mql нельзя.
дерзко :)
 
дерзко :)

Не подумайте, что я в вашу сторону это написал :)

Просто, например, как я это делаю в delphi:

var
  p: PAnsiChar;
begin
  GetMem(p, 256); // вот как я выделяю память. А как это в mql сделать - хрен бы его знал :(
  if GlobalGetAtomNameA(MyAtomIndex, p, 255) <> 0 then
    result := StrPas(p)
  else
    result := '';
  FreeMem(p);
end;