Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

AccessViolation непонятно с чего [D6, WinXP]


Страницы:   1 2

Alexandr3 ©   (2005-03-10 08:49:00) 

Ниже привожу код  в котором при закоментировании строки
Element[5]:= 'First_Name'; все проходит при раскоментированной строке отладчик выдает сабж уже на строке

@htinit := GetProcAddress(LibHandle,'HTINIT');
Помогите пожалуйста
Воообще если кто работал с HyTech Базами буду благодарен за небольшой пример создания таблицы.

var

Element:TElement;
httablecreate:Function(ptablename:Pchar;fpelement:TElement ;nElems:integer;fpCryptoKey:Pchar;fpReadPswd:Pchar;fpWritePswd:Pchar;nOpenMode:integer;fpHandle:THandle):integer;
 htshut:function():integer;
 gh:integer;
 Form1: TForm1;
 LibHandle:Thandle;
 htinit:function(LangRus: pointer;rrr:Integer): integer;

 implementation

uses htdefs;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin

 LibHandle:=LoadLibrary('HTW32PAS.DLL') ;
 @htinit := GetProcAddress(LibHandle,'HTINIT');
@htTableCreate := GetProcAddress(LibHandle,'HTTABLECREATE');
htinit(nil,20) ;
Element[0]:=10;
Element[1]:=0;
Element[2]:= EC_FIELD;
Element[3]:=ET_CHAR;
Element[4]:=EK_NOTKEY;
Element[5]:= 'First_Name';
//htTablecreate('c:\rtr',Element,1,'paswd',nil,nil,128,gh) ;
Edit1.Text:='dfva';


icWasya   (2005-03-11 12:47:00) [1]

to Anatoly Podgoretsky ©   (10.03.05 20:00) [21]
>Интересная у тебя справка.
Это я по памяти. А так Вы правы.

должно быть так
Если используется режим pascal, то параметры грузятся в стек в том порядке, в каком они встречаются в тексте. При выходе из процедуры она сама убирает параметры из стека. Используется для совместимости со старыми программами.

safecall- с параметрами то же что и stdcall, плюс специальный механизм обработки исключений для OLE/COM


Defunct   (2005-03-11 02:23:00) [2]

Alexandr3   (10.03.05 12:05) [13]
> но хотелось бы понять причину сабжа в моем начальном случае я же там ничего не вызываю где этот массив используется только

Причина проста как мир. Вы компилировали с выключенным Range Check. Поскольку httablecreate располагалась непосредственно за Element, и вы получали адрес httablecreate до заполнения структуры Element, то нормально полученный адрес httablecreate затирался какой-то чипухой на строке Element[5]:= 'First_Name';

могу поспорить, что если бы в вашем изначальном коде
Element:TElement;
httablecreate:Function


между объявлениями Element и httablecreate было бы что-то eще, AV вы бы не получили, и маялись бы в поисках ошибки гораздо дольше:

Element:TElement;
TempSpace: Array[1..10000] of byte;
httablecreate:Function;


Anatoly Podgoretsky   (2005-03-10 20:00:00) [3]

icWasya ©   (10.03.05 18:21) [19]
Интересная у тебя справка.

Alexandr3   (10.03.05 12:33) [18]
Calling Convention


Набережных С.   (2005-03-10 19:54:00) [4]


> icWasya ©   (10.03.05 18:21) [19]
> Если используется режим safecall, (OLE, COM), то параметры
> грузятся в стек в том порядке, в каком они встречаются в
> тексте

Нет, не так. При SafeCall реально используется stdcall.


icWasya   (2005-03-10 18:21:00) [5]

stdcall+F1
ну а по русски так -
в Delphi используются четыре режима передачи параметров
fastcall(по умолчанию), cdecl, stdcall, и safecall
Если используется режим fastcall, (или нет никакого уточнения), то несколько параметров передаются через регистры, остальные грузятся в стек в том порядке, в каком они встречаются в тексте. При выходе из процедуры она сама убирает параметры из стека.
Если используется режим cdecl, (по умолчанию в C/C++) то параметрs грузятся в стек в порядке, обратном тому, в каком они встречаются в тексте. При выходе из процедуры она оставляет  параметры в стек.

Если используется режим stdcall, (почти все стандартные API процедуры), то параметры грузятся в стек порядке, обратном тому, в каком они встречаются в тексте. При выходе из процедуры она сама убирает параметры из стека.

Если используется режим safecall, (OLE, COM), то параметры грузятся в стек в том порядке, в каком они встречаются в тексте. При выходе из процедуры она сама убирает параметры из стека.

Обратный порядок загрузки параметров сделан для возможности использовать в C/C++ процедуры с переменным числом параметров.


Alexandr3   (2005-03-10 12:33:00) [6]

Где бы подробно почитать про типы вызовов


MU   (2005-03-10 12:22:00) [7]

int HTAPI htInit(
LPINIT fpParms, /* Адрес структуры с параметрами */
int  nParmLen /* Длина структуры параметров */
);
//
...
int rc;
if( (rc = htInit( NULL, 0 )) < 0 )
{ printf( "Ошибка инициализации HyTech: %s\n", htMessage(rc) );
exit 1;
}


Alexandr3   (2005-03-10 12:21:00) [8]

работает конечно спасибо большое
но непонятно что вызывает сабж в чисто теории
если не указывать stdcall;где она передает параметры
и с какая связь между количеством инициализируемых
параметров массива и типом вызова функции


icWasya   (2005-03-10 12:20:00) [9]

to Alexandr3   (10.03.05 12:05) [13]
> используется только htinit

В Вашем коде htinit описана так
htinit:function(LangRus: pointer;rrr:Integer): integer;
а в DLL скорее всего так
int HTAPI htinit(void *LangRus, int rrr);
по этому вызов этой процедуры уже вызовет нарушение стека с непредсказуемым результатом.


MU   (2005-03-10 12:13:00) [10]

htinit:function(LangRus: pointer;rrr:Integer): integer; stdcall;


Alexandr3   (2005-03-10 12:05:00) [11]

Да про вызовы я понял спасибо
но хотелось бы понять причину сабжа в моем начальном случае я же там ничего не вызываю где этот массив используется только
нtinit
httablecreate закоментированна


MU   (2005-03-10 12:01:00) [12]


> icWasya ©   (10.03.05 11:23) [9]
> И не забывать о соглашении о вызовах. Всякие там stdcall,
> cdecl  и иже с ними

httablecreate:Function(ptablename:Pchar;fpelement:TElement ;nElems:integer;fpCryptoKey:Pchar;fpReadPswd:Pchar;fpWritePswd:Pchar;nOpenMode:integer;fpHandle:THandle):integer; stdcall;
htinit:function(LangRus: pointer;rrr:Integer): integer; stdcall;


Alexandr3   (2005-03-10 11:49:00) [13]

Все таки не понятно что вызывает Сабж вылетает то он
раньше чем даже инициализируется первый элемент массива
и при 5 элементах не вылетает


Alexandr3   (2005-03-10 11:23:00) [14]

Все таки не понятно что вызывает Сабж вылетает то он
раньше чем даже инициализируется первый элемент массива
и при 5 элементах не вылетает


icWasya   (2005-03-10 11:23:00) [15]

И не забывать о соглашении о вызовах. Всякие там stdcall, cdecl и иже с ними.


Alexandr3   (2005-03-10 11:06:00) [16]

Спасибо огромное действительно не доконца прочитал документацию.


MU   (2005-03-10 10:56:00) [17]

вот описание ELEMENT (искал за вас...)
http://linux.nist.fss.ru/skaz-mir/doc/v25/local/low/str_ELEMENT.htm
из чего  следует, что это структура (record) и передается массив
структур ELEMENT, а не двумерный массив


Alexandr3   (2005-03-10 10:36:00) [18]

Не  понимаю при  чем тут запись если в параметры функции
входит  int nElemCnt
задает число элементов таблицы (размерность массива описателей).
При предложенном подходе з записью размерность массива всегда будет=1
и вот описание примера для билдера
где тут запись
ELEMENT asElem[] = {
{ 10, 0, EC_FIELD, ET_CHAR, EK_NOTKEY, "Frst_Name" },
{ 10, 0, EC_FIELD, ET_CHAR, EK_NOTKEY, "Scnd_Name" },
{ 0, 0, EC_FIELD, ET_BYTE, EK_NOTKEY, "Sex" },
{ 0, 0, EC_FIELD, ET_WORD, EK_NOTKEY, "Salary" },
/* Группа, включающая первое и второе имя, образующая ключ */
{ 2, 1, EC_GROUP, ET_CHAR, EK_COMMON, "Name" },
/* Подстрока от второго имени, состоящая из первых пяти символов */
{ 1, 2, EC_SUBSTR, 5, EK_COMMON, "Substr" }
};
я вижу массив 6:6
кроме того больше непонятно чем delphi не устраивает добавление одной строки в моем конкретном случае


MU   (2005-03-10 10:18:00) [19]

есть ли у вас объявление/описание структуры ELEMENT?

кажется, TElement надо объявить как record
type
TElement = record
 wOffset : word;
 wLength : word;
 cType   : byte;
 ...
end;

var
Elements : array [N..M] of TElement;


Alexandr3   (2005-03-10 10:08:00) [20]

В описании функции ясно сказано что asElem указатель
на массив описателей элементов таблицы.
Кроме того в примере для Билдера
ELEMENT asElem[] = {
{ 10, 0, EC_FIELD, ET_CHAR, EK_NOTKEY, "Frst_Name" },
{ 10, 0, EC_FIELD, ET_CHAR, EK_NOTKEY, "Scnd_Name" },
{ 0, 0, EC_FIELD, ET_BYTE, EK_NOTKEY, "Sex" },
{ 0, 0, EC_FIELD, ET_WORD, EK_NOTKEY, "Salary" },
/* Группа, включающая первое и второе имя, образующая ключ */
{ 2, 1, EC_GROUP, ET_CHAR, EK_COMMON, "Name" },
/* Подстрока от второго имени, состоящая из первых пяти символов */
{ 1, 2, EC_SUBSTR, 5, EK_COMMON, "Substr" }
};
То же кажется не структура хотя я в си не силен
И вообще не понятно главное почему это срабатывает когда присваивается 5 Элеменов
и сабж раньше первого присваивания когда 6
Еще в одной умной книжке прочитал что перерменной типа вариант нельзя присвоить значение обычного статического массива
а надо использовать VarArrayCreate
Насколько корректно такое объявление
type TElement=array[0..5] of variant;
var
Element:Telement  ???


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо