Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Вниз

AccessViolation непонятно с чего   Найти похожие ветки 

 
Alexandr3   (2005-03-10 08:49) [0]

Ниже привожу код  в котором при закоментировании строки
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";


 
Anatoly Podgoretsky ©   (2005-03-10 09:10) [1]

А где объявление httablecreate в библиотеке, хочешь, чтобы мы помедитировали?


 
Alexandr3   (2005-03-10 09:31) [2]

Честно говоря не совсем понял вопрос учитывая что в данном случае
httablecreate не вызывается (закоментированна )
а при закоментированной
Element[5]:= "First_Name
адрес функции httablecreate возвращается нормально
Ниже описание функции из документации и еще
TElement oбъявлен как  
type TElement=array[0..5] of variant;

htTableCreate - Создать новую таблицу
Назначение:
Функция служит для создания новой таблицы. Если таблица с заданным именем уже существует, поведение функции зависит от флага TAB_CREATE . Для сброшенного флага операция завершится с ошибкой. Если флаг установлен, функция уничтожит старую таблицу и создаст новую.

При создании или открытии СУБД присваивает таблице некий номер - "обработчик". Этот номер будет идентифицировать таблицу при последующих операциях поиска или обработки данных. При создании или открытии таблицы нужно указать флаги доступа, задающие режим использования таблицы (монопольный или совместный), возможность модификации данных и пр.

При задании ключа крипто-закрытия выполняется шифрование данных как в постоянной части таблицы, так и журнале изменений. Также шифруется часть ассоциатора, содержащая индексы ключевых полей. При шифровании применятся алгоритм, использующий заданный пароль, что ограничивает доступ к данным лиц, имеющих те же программные средства, но не знающих пароль закрытия. Кроме шифрования данных возможно закрыть доступа к таблице паролем для чтения (поиска) или модификации. Последующие операции чтения (поиска) таблицы возможны только при указании пароля доступа на чтение. А операции модификации - еще и пароля доступа на запись.

Прототип:
int HTAPI htTableCreate(
 char far  *fpTableName, /* Имя таблицы (можно без расширения) */
 LPELEMENT fpElems,      /* Описатели элементов таблицы */
 int       nElemCnt,     /* Число описателей элементов */
 char far  *fpCryptoKey, /* Ключ для крипто-закрытия данных */
 char far  *fpReadPswd,  /* Пароль для доступа на чтение */
 char far  *fpWritePswd, /* Пароль для доступа на запись */
 int       nOpenMode,    /* Режим открытия (константы TAB_???? ) */
 LPTHANDLE fpHandle      /* Для приема обработчика таблицы */
);
Параметры:
fpTableName
имя файла описания таблицы (с указанием полного или частичного пути), расширение задавать не обязательно
fpElems
задает адрес массива описателей элементов таблицы. Описания производных элементов записи (группы и подстроки) должны располагаться после описания полей. В поле таких элементов указывается:
wOffset
порядковый номер (отсчет от 1) первого поля таблицы, входящего в группу или образующего подстроку
wLength
для группы указывается число смежных полей, образующих группу. Для подстроки содержит смещение подстроки относительно начала образующего поля (отсчет от 1)
cType
Длина подстроки (тип подстроки может быть только ET_CHAR).
nElemCnt
задает число элементов таблицы (размерность массива описателей).
fpCryptoKey
задает строку, используемую в качестве пароля для крипто-закрытия данных. Значащими являются только первые 8 символов. Если пароль не нужен, можно задать NULL или пустую строку "".
fpReadPswd
задает строку, используемую в качестве пароля для доступа к таблице на чтение. Значащими являются только первые 8 символов. Если пароль не нужен, можно задать NULL или пустую строку "".
fpWritePswd
задает строку, используемую в качестве пароля для доступа к таблице на запись. Значащими являются только первые 8 символов. Если пароль не нужен, можно задать NULL или пустую строку "".
nOpenMode
задает флаги открытия ( TAB_??? )
fpHandle
задает адрес переменной для занесения обработчика создаваемой таблицы.

Результат:
0 при успешном завершении
отрицательное число код ошибки

Пример.
Создать таблицу из четырех полей с шифрованием данных и свободным доступом на чтение/запись для локального использования. Кроме полей, таблица будет содержать группу (ключ, объединяющий первые два поля) и подстроку (ключ, состоящий из части второго поля).

/* При создании таблицы смещение полей рассчитывает СУБД */
/* Длина поля имеет смысл только для символьных полей */
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" }
};
THANDLE hNew;
int rc;
rc = htTableCreate( "staff", asElem, sizeof(asElem) / sizeof(ELEMENT),
 "password", NULL, NULL, TAB_PRIVATE, &hNew );
if( rc < 0 )
/* Обработка ошибок */


 
MU ©   (2005-03-10 09:50) [3]

кажется, TElement надо объявить как record


 
Alexandr3   (2005-03-10 10:08) [4]

В описании функции ясно сказано что 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  ???


 
MU ©   (2005-03-10 10:18) [5]

есть ли у вас объявление/описание структуры 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:36) [6]

Не  понимаю при  чем тут запись если в параметры функции
входит  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:56) [7]

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


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

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


 
icWasya ©   (2005-03-10 11:23) [9]

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


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

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


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

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


 
MU ©   (2005-03-10 12:01) [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 12:05) [13]

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


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

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


 
icWasya ©   (2005-03-10 12:20) [15]

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);
по этому вызов этой процедуры уже вызовет нарушение стека с непредсказуемым результатом.


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

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


 
MU ©   (2005-03-10 12:22) [17]

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:33) [18]

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


 
icWasya ©   (2005-03-10 18:21) [19]

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

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

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

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


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


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

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


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

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

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


 
Defunct ©   (2005-03-11 02:23) [22]

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;


 
icWasya ©   (2005-03-11 12:47) [23]

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

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

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



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.044 c
14-1110098306
Dann
2005-03-06 11:38
2005.03.27
Прокладка кабельных коробов


1-1110459740
Aleks
2005-03-10 16:02
2005.03.27
какой компонент нужно использовать???


1-1110714640
Object
2005-03-13 14:50
2005.03.27
Куда прописать файлы *.dcr;*.dcu;*.hpp;*.obj...


9-1104390790
макс
2004-12-30 10:13
2005.03.27
Glearthskydome


4-1108577833
mordush
2005-02-16 21:17
2005.03.27
Процессы в системе





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский