cdecl - как это работает и для чего это?

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: cdecl - как это работает и для чего это?

Сообщение debi12345 » 24.03.2013 17:01:37

Chunk.size

Где устанавлвивается это значение ? Какие значения для него показывает отладчик ?
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 17:09:54

debi12345 писал(а):Где устанавлвивается это значение ? Какие значения для него показывает отладчик ?

1) Значения записаны в файле.
2) Они наверно идентифицируются правильно: 12, 54, 338, 1234254 и т.д.

Добавлено спустя 2 минуты 53 секунды:
Дело не в Chunk.size, я заменил на единичку - всё равно падает.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение debi12345 » 24.03.2013 17:32:57

Где находится колбэк-функция ? В С-ой ДЛЛ ? Есть ее код ? Нужно пошагово в отладчике смотреть - что она делает в памяти.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 17:37:35

Никаких Dll нет.
Это выглядит вот так:
1) в шапке модуля: TReadCallback = procedure(Chunk: TChunkRec; Data: Pointer); cdecl;
2) в функции: LoadFromStream(Stream: TStream; ReadCallback: TReadCallback; UserData: Pointer): LongWord;
3) а это тело цикла while функции LoadFromStream:
Код: Выделить всё

Read(Chunk,8);
ReverseByteOrder(@Chunk.size,4);
StartPos:=Position;
GetMem(Chunk.data,Chunk.size);
Stream.Read(Chunk.data^,Chunk.size);
if Assigned(ReadCallback) //( if Assigned(ReadCallback) - работает нормально) в смысле Assigned...
    then ReadCallback(Chunk,UserData);  // <== а вот здесь модуль всегда падает... если закомментировать то проходит весь stream
FreeMem(Chunk.data,Chunk.size);
Position:=StartPos+Chunk.size+(StartPos+Chunk.size) mod 2;



.

Добавлено спустя 18 минут 9 секунд:
В модуле в параллельной функции:
в разделе public, можно получить:
1) property Data: Pointer read FData;
2) property Size: LongWord read FSize;

:?: Как мне дешифровать содержимое Data, чтобы поместить в TMemo?
:arrow: вот так? ==> побайтово конвертирвать "Byte((data+i)^)" в "char"?



.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение debi12345 » 24.03.2013 18:07:59

Никаких Dll нет.

А зачем тогда понадобилось CDECL ?

Как мне дешифровать содержимое Data,

Сперва нужно его просто получить в память - без вылета из программы :) И потом уже дешифровать.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 18:17:53

debi12345 писал(а):А зачем тогда понадобилось CDECL ?

CDECL - это что вызов функции из dll? .. тогда это какая-то стандартная dll...
:?: А может это быть не Dll? а какой нить код, который размещён в соседнем модуле?

debi12345 писал(а):Сперва нужно его просто получить в память - без вылета из программы

В модуле два варианта загрузки файла. Один я починил и он загружает файл и заносит данные в FData,
соответственно FDATA - можно прочитать.
А второй вариант загрузки это то что приведено в примерах в данном топике.
Я хотел восстановить второй вариант, т.к. модуль подключается параллельно с 10 идентичными модулями и отвечает за определённое расширение. Но он при подключении валится. Я думаю что сбой во второй функции т.к. первая работает. И там проследить по коду не получается, т.к. Ctrl+клик ведёт в тупик.

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

:?: Как мне дешифровать содержимое FData : Pointer?
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение debi12345 » 24.03.2013 19:52:28

заносит данные в FData,
соответственно FDATA - можно прочитать.

Что показывает отладчик ? В структуре сидят правильные данные ? Размеры в порядке ? Такие вещи делаются имено в отладчике :)

для этого нужно дешифровать FData: Pointer.

Какими байтами в в этом пойнтере предствалено например число 123.45 ? Нужно ли вызывать Int(Float)ToStr Или достаточно посимвольной конкатенации ?
По ID типа выбрать нужный декодировщик - Int(Float)ToStr,.. и передать ему

А я никогда этого не делал... Вроде всё понимаю... а как это делается не знаю Знаний и опыта - не хватает

И замахнулись на нестандртные деккларации :)

А может это быть не Dll? а какой нить код, который размещён в соседнем модуле

С точки зрения применимости в FPC:
CDECL - нужно для обращения к DLL, написаным на С
STDCALL (помесь CDECL & PASCAL) - нужно для обращения к DLL, представляющим win32 API.
Все остальное - PASCAL (по умолчанию).
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: cdecl - как это работает и для чего это?

Сообщение bormant » 24.03.2013 20:13:24

vitaly_l,
у вас LoadFromStream() читает из файла порцию данных (chunk); затем вызывает вашу функцию, передавая ей по значению считанные данные и ваш же пользовательский указатель; затем освобождает память. Всё это повторяется, пока не закончится файл (скорее всего, этот код вы не приводили).

Как интерпретировать считанные данные, дело сугубо ваше, этот вопрос находится за пределами описанного алгоритма.

От вас требуется реализовать что-то вроде:

procedure MyHandler(Chunk: TChunkRec; Data: TMemo); cdecl;
begin
// в Data будем получать указатель на TMemo
// ... как-то обрабатываем Chunk
Data.Lines.Add( "какие-то данные" );
end;

чтобы потом передать в вызов

Readed := LoadFromStream(Stream, @MyHandler, Memo1);
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 20:29:35

debi12345 писал(а):Такие вещи делаются именно в отладчике

Я не Земной программист, а инопланетянин - для меня отладчиком является TMemo...
:cry: Что Вы называете отладчиком? В Лазарусе есть только кнопка "сбросить отладчик"...

debi12345 писал(а):Какими байтами в в этом пойнтере предствалено например число 123.45 ? Нужно ли вызывать Int(Float)ToStr Или достаточно посимвольной конкатенации ?

Да хоть как нибудь вывести бы - этот чёртов стэк... :evil:
Как только я смогу получить содержимое в любом понятном для меня виде например array of string, мне этого будет достаточно.

debi12345 писал(а):И замахнулись на нестандртные деккларации

Я ни на что не замахивался... это не мой код... я просто никогда не пользовался стэками, мне для моих задач хватало array. Хотя стэк наверно быстрее.

debi12345 писал(а):CDECL - нужно для обращения к DLL, написаным на С

Там точно нет никакой Dll - это из GLScene, открытый код.

bormant писал(а):чтобы потом передать в вызов
Readed := LoadFromStream(Stream, @MyHandler, Memo1);

Тобишь заменить на свою функцию типа MyHandler... Такого быть не может... остальные расширения грузятся без dll и без моей функции... Либо эта функция априори нерабочая и не участвует в загрузке, а работает только вторая.

Кстати!... Посмотрю как в других модулях организован LoadFromStream... Может там есть...?

bormant писал(а):... как-то обрабатываем Chunk

Вот это я и хочу понять... как его нужно обработать... чтобы переместить данные в нужный мне буфер... но у меня не получается получить данные в понятном мне виде... вот... нажаловался... :oops: :cry: :evil:




.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение bormant » 24.03.2013 20:44:18

vitaly_l писал(а):у меня не получается получить данные в понятном мне виде
Это не на форуме, это в документации по формату файла искать надо, как данные того или иного чанка интерпретировать.

В качестве минимально понятного формата могу предложить 16-ричный дамп.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 20:58:01

bormant писал(а):это в документации по формату файла искать надо

Я её как раз только прочитал... там только общие поверхностные данные...
типа: Load функция для загрузки... Clear функция для очистки... итп...
Коротеч, грязная вода есть... а самого необходимого как всегда нет...

Добавлено спустя 1 минуту 30 секунд:
Неужели нет никакого стандартного метода интерпретировать содержимое data : pointer из стэка?



/
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение debi12345 » 24.03.2013 21:02:32

Да хоть как нибудь вывести бы - этот чёртов стэк...

1) на "падающей" функции назначить точку остнова
2) как остановится - выпонять прграмму пошагово, глядя в содержимое памяти

Как в Лазарусе смортеть в память из отлдачика в формате исходой структуры (название переменной = ее значение) - не помню (пользуюсь MSE*), но 100% это есть.

Неужели нет никакого стандартного метода интерпретировать содержимое data : pointer из stream?

Есть - у компонента "TArtificialIntellectLikeHumanStream".
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 21:04:54

Добавлено спустя 55 секунд:
debi12345 писал(а):1) на "падающей" функции назначить точку остнова
2) как остановится - выпонять прграмму пошагово, глядя в содержимое памяти

Хождение по коду ассемблера Вы называете отладчиком?
Там два перехода: со входом и в обход... И даже с учётом того что я понимаю 10-20% из ассемблерного кода,
я твёрдо уверен что, найти в ассемблере ошибку... Для меня сверх сложная задача... Чтобы читать ассемблер нужно в нём жить...
Мне проще новый язык для машинного кода придумать нежели читать и понимать ассемблер.


bormant писал(а):Это не на форуме, это в документации по формату файла искать надо, как данные того или иного чанка интерпретировать.

:idea: :?: А можно их все интерпретировать в string? Мне нужно понять схему считывания из стэка.




.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: cdecl - как это работает и для чего это?

Сообщение bormant » 24.03.2013 21:30:44

vitaly_l писал(а):Мне нужно понять схему считывания из стэка.
Не нужно. Вам содержимое чанка приходит готовое, размер в Size, данные в Data^.
А вот что с данными делать, как их интерпретировать -- это читайте в документации на формат.

Вот вам упрощённый пример использования методики с обратным вызовом (и даже с тем же соглашением о вызове -- cdecl):
Исходные данные (tst.txt):
Код: Выделить всё
1
Это фрагмент 1 из 1 строки
2
Это фрагмент 2
из 2 строк
3
Это фрагмент 3
из 3
строк
1
Это фрагмент 4 из 1 строки

Исходный код:
Код: Выделить всё
// это нам дано
const
  EOL = #13#10;
type
  PChunkRec = ^TChunkRec;
  TChunkRec = record
    Size: integer;
    Data: pointer;
  end;

  TReadCallback = procedure(Chunk: TChunkRec; Data: Pointer); cdecl;

procedure LoadFromFile(var F: text; ReadCallback: TReadCallback; UserData: Pointer);
var
  Chunk: TChunkRec;
  s, l: string;
  i, n: integer;
begin
  while not SeekEof(F) do with Chunk do begin
    ReadLn(F, n); s := '';
    for i := n downto 1 do begin ReadLn(F, l); s := s + l + EOL; end;
    Size := Length(s) + 1; GetMem(Data, Size);
    Move(s[1], Data^, Size - 1); (PChar(Data) + Size - 1)^ := #0;
    if ReadCallback <> nil then ReadCallback(Chunk, UserData);
    FreeMem(Data);
  end;
end;

// это дописываем мы для работы LoadFromFile
procedure MyHandler(Chunk: TChunkRec; UserData: Pointer); cdecl;
begin
  with Chunk do WriteLn(Size, EOL, PChar(Data));
end;

var
  f: text;

begin
  Assign(f, 'tst.txt'); Reset(f);
  LoadFromFile(f, @MyHandler, nil);
  Close(f);
end.
Прогон:
Код: Выделить всё
29
Это фрагмент 1 из 1 строки

29
Это фрагмент 2
из 2 строк

30
Это фрагмент 3
из 3
строк

29
Это фрагмент 4 из 1 строки


Надеюсь, так технология понятнее стала?
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: cdecl - как это работает и для чего это?

Сообщение vitaly_l » 24.03.2013 21:53:14

bormant писал(а):Надеюсь, так технология понятнее стала?

Да, так немного прозрение наблюдается...
По крайней мере это код, который можно увидеть и
интерпретировать на мой инопланетянский язык программирования.
90% мне понятно - остальное допойму в процессе.

Спасибо...



.

Добавлено спустя 20 минут 40 секунд:
Move(s[1], Data^, Size - 1); <== вот здесь непонятно почему s[1]??? А просто s почему нельзя? Зачем [1]???
(PChar(Data) + Size - 1)^ := #0; <== вот этот код, не понимаю, что делает?

:?: Если несложно, буквально в двух словах, разъясните - пожалуйста. :oops: :cry:


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 6

Рейтинг@Mail.ru