![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
AccessViolation непонятно с чего [D6, WinXP]
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 ???