Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.01.2008, 08:52   #1
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию Массивы

В общем проблема такого характера... По клику на кнопке вызывается некоторая функция WinAPI, которая помимо всего прочего возвращает указатель на массив байт. Этот массив мне необходимо интерпретировать как массив структур заданного типа. Для этого я подготавливаю такой массив (динамический) и с помощью Move копирую туда возвращенные данные. Данные копируются и читаются далее абсолютно нормально. Проблема возникает при выходе из обработчика клика кнопки, вылетает Access violaton. Не могу понять, почему? Или может есть другой способ решить траблу?

Последний раз редактировалось Баламут; 12.01.2008 в 08:54.
Баламут вне форума Ответить с цитированием
Старый 12.01.2008, 13:55   #2
Dark_Elf
 
Аватар для Dark_Elf
 
Регистрация: 12.12.2007
Сообщений: 7
По умолчанию

Покажи процедуру обработки.
Dark_Elf вне форума Ответить с цитированием
Старый 12.01.2008, 14:38   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Скорей всего неверно указан размер блока данных при перемещении в памяти Вы наверняка затераите другие данные и при выходе получаете такую проблему. Да конечно есть выход немного другой опеределить допустим Вашу структуру на нее указатель то пусть массив байт b: array[0..N] of BYTE; структура TStruct = packed record... PStruct = ^TStruct; так вот попробуйте типа такого PStruct := @b; а потом обращаться с PStruct^.поле
BOBAH13 вне форума Ответить с цитированием
Старый 12.01.2008, 14:48   #4
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
Да конечно есть выход немного другой опеределить допустим Вашу структуру на нее указатель то пусть массив байт b: array[0..N] of BYTE; структура TStruct = packed record... PStruct = ^TStruct; так вот попробуйте типа такого PStruct := @b; а потом обращаться с PStruct^.поле
Это с переменной так получается. С массивом что-то не проходит.
Баламут вне форума Ответить с цитированием
Старый 12.01.2008, 14:49   #5
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Цитата:
Сообщение от Dark_Elf Посмотреть сообщение
Покажи процедуру обработки.
Слишком уже разрослась. Да и не в ней дело. Проблема в строке Move(...
Баламут вне форума Ответить с цитированием
Старый 12.01.2008, 15:23   #6
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

если массив вида b: array of BYTE; то можно PStruct := b; ( без оператора @ ). Просто мне кажется в данном случае нет смысла копировать. Точней Вы не могли бы все дать ?! Move - процедура работает идеально. Вы гдет ошибаитесь, но без представления хотя куска где Move и ее переменных врятли кто Вам поможет.
BOBAH13 вне форума Ответить с цитированием
Старый 12.01.2008, 16:16   #7
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Ну если хотите...
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,jwaWinSvc, jwaWinNT, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
     lpBuffer: PByte;
     BufSize: DWORD;
     BytesNeeded: DWORD;
     hService: THandle;
     PFailServices: TSERVICEFAILUREACTIONS;
     sc: array of TSCACTION;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
QueryServiceConfig2(hService,SERVICE_CONFIG_FAILURE_ACTIONS,
lpBuffer,BufSize, BytesNeeded);

BufSize := BytesNeeded;
GetMem(lpBuffer, BytesNeeded);
QueryServiceConfig2(hService,SERVICE_CONFIG_FAILURE_ACTIONS,
lpBuffer,BufSize, BytesNeeded);
Move(lpBuffer^, PFailServices,BufSize);

SetLength(sc, pFailServices.cActions* SizeOf(TscAction));
Move(PFailServices.lpsaActions^,sc,SizeOf(TscAction)*PFailServices.cActions);
end;

end.
Сами понимаете, что описание всех структур и т.д. тянет на книгу... Компилировать этот код бессмысленно без контекста
Баламут вне форума Ответить с цитированием
Старый 12.01.2008, 17:19   #8
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Я освобождения не вижу )) freeMem(lpBuffer); Потом перед Move(lpBuffer^, PFailServices,BufSize); я бы посоветовал сравнить BufSize и BytesNeeded ( если конечно QueryServiceConfig2 чтот меняет, я незнаю что это даже ) И в какой из Move проблема ? А хотя меня очень заинтриговали две последнии строки... вот в них может и быть проблема при таком способе присваивания. Т.к. sc - массив и Вы его устанавливаете с помощью SetLength - а не через GetMem, а после используете Move. Мне кажется вся проблема в двух последних строках.
BOBAH13 вне форума Ответить с цитированием
Старый 12.01.2008, 17:29   #9
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Вопрос с присваиванием и освобождением опустим, т.к. здесь лишь обрывки из реального кода. Все это есть. Но все-таки мне интересно, в чем разница между GetMem и SetLength в данном случае?
Баламут вне форума Ответить с цитированием
Старый 12.01.2008, 18:57   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Я точно сказать не могу. Но по наблюдениям после SetLength - delphi самостоятельно освобождает ресурсы, а вот после GetMem - совсем иная ситуация, т.е. приходится вызывать FreeMem. Так что возможна ситуация например ?! Откуда Length знает длинну данных выделенную с помощью SetLength - явно данная процедура выделяет кусок для хранения вспомогательных данных, а вот GetMem - ему сколько сказал выделить он и выделет, так что возможно именно из-за тех вспомогательных данных вся проблема.

Последний раз редактировалось BOBAH13; 12.01.2008 в 18:59.
BOBAH13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Массивы в С\С++ Zahar11 Помощь студентам 4 31.05.2008 00:35
массивы ShenDy Общие вопросы C/C++ 4 17.04.2008 00:01
Массивы Snord Общие вопросы Delphi 2 12.04.2008 13:45