Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проблемы с интерфейсом dll


Автор: Hamster 23.6.2003, 00:29
Код
unit example;

interface

type
 TEST_OPERATION = record
   sum: Single;                              // operation sum
   price: Single;                            // sale price
   min: Byte;
   hour: Byte;
   day: Byte;
   month: Byte;
   year: Word;
 end;

 TEST_JOURNAL = record
   session: Word;                      
   cal: ByteBool;                    
   oper_count: Word;                    
   operations: array of TEST_OPERATION;
 end;

function test_read(p_type, port: Integer; out test: TEST_JOURNAL): Integer; cdecl;
 external 'test.dll';
function test_done(var test: TEST_JOURNAL): Integer; cdecl; external 'test.dll';

implementation

end.


Доброго вам времени суток господа.
У меня возникла проблема с вот этой структурой данных.
Есть откомпилиная библиотека к которой забыли прикрипить сырцы(так их так всех на той конторе).
Но есть интерфейс описанный выше! Данные из TEST_JOURNAL ( session, cal, oper_count ) получаю без проблем.
Но вот с массивом operations возникла проблема! Не могу я получить от туда данные и всё!
Вот код которым я пользовал эту библиотеку!

Код

procedure TForm1.Button2Click(Sender: TObject);
begin
test_read(2,2,data);
memo1.Lines.Add(inttostr(data.session)+' номер последней закрытой сессии');
memo1.Lines.Add(inttostr(data.oper_count)+' число элементов в масиве операций');
memo1.Lines.Add(inttostr(byte(data.cal))+' признак режима');
memo1.Lines.Add(floattostr(single(@data.operations[1].sum)));
memo1.Lines.Add(floattostr(single(@data.operations[2].sum)));
memo1.Lines.Add(floattostr(single(@data.operations[3].sum)));
memo1.Lines.Add(inttostr(byte(@data.operations[1].day)));
end;


Так вот не работает.
Помогите плз кто чем сможет.
Заранее благодарен.

Автор: acp 23.6.2003, 05:20

Попробуй доступаться к массиву с 0-го элемента.

Автор: Guest_Hamster 24.6.2003, 22:17
К сожалению это не помогает!
Скорее всего здесь, у меня что то с синтаксисом! ;(
Help!

Автор: acp 24.6.2003, 23:29

Тогда может функции в dll подразумевают, что тот, кто их вызывает, должен сам создавать массив?

Автор: Fantasist 25.6.2003, 01:07
Цитата
(@data.operations[1].sum)));


зачем взятие адреса стоит?

Автор: Hamster 25.6.2003, 04:28
Затем, что если без этого, то выдаёт ошибку чтения адреса памяти.

Автор: acp 25.6.2003, 17:17

Fantasist правильно всё сказал, это я что-то... smile.gif

А ошибку выдаёт потому, что массива не существует, когды вы пытаетесь к нему доступиться.

Автор: Fantasist 25.6.2003, 20:41
Цитата
Затем, что если без этого, то выдаёт ошибку чтения адреса памяти.



Мда... Более удачное объяснение редко приходится слышать. smile.gif Программируем исключительно методом научного тыка? Я тогда вот что посоветую, убери обращение к массиву и поставь там просто случайно сгенерированное число. Тебе ведь все равно, что за данные ты получаешь? Какая разница то ли это адрес какой-то переменной, то ли случайно число.

Автор: Hamster 26.6.2003, 02:07
Да! Метод научного тыка всегда выручал smile.gif но только не в этом случае. Я пытался и массив и запулить туда данные, всё одно. Ну не получается и всё. А прикалываться тут не уместно!!! Подсказал бы чего, а не подшучивал! Бывает, что я не знаю элементарных вещей, которые описаны в книгах. Но это только потому, что у меня небыло ещё ни одной книги по программированию, кроме старого справочника паскалевских функций. Так что не пинайте ногами по возможности.

Автор: Fantasist 26.6.2003, 02:23
Цитата
Но это только потому, что у меня небыло ещё ни одной книги по программированию


Книги книгами, но есть же help и есть соображаловка. smile.gif Желательно понимать, что ты такое написал и каким образом это работает. Потому как если просто тассовать выражение, пока хоть как-то не заработает, то вот на такие вещи и будешь напарываться - вроде работает, а делает что-то не то.

Без исходников dll тут наверняка сказать ничего нельзя. Попробуй изменить:
function test_read(p_type, port: Integer; var test: TEST_JOURNAL): Integer; cdecl;
external 'test.dll';

и сделать:

procedure TForm1.Button2Click(Sender: TObject);
begin
SetLength(data.operations,3);
test_read(2,2,data);
...
end;

Автор: KAS 26.6.2003, 18:27
Похоже, Hamster, мы пали невинными жертвами на одной войне. У меня тут рядом висит вопрос, называется "Интеграция Delphi и Fortran".
Вообще попробуй с другими директивами stdcall, safecall, хотя последняя делалась специально для стандартных Windows API DLL-ов, но чем черт не шутит.(Это , конечно, не поможет но попробовать надо)
И еще, не в курсе ли ты на каком СИ писана твоя програма (MS Visual C++, Visual Studio или еще какой)?
Я страдаю с фортраном 6.0 от Visual Studio.

Кстати для Fantasist-а: метод научного тыка действительно не лучший, но, к сожалению, в реалиях Советской России один из наиболее эффективных для целого ряда задач про которые у нас
никто ничего не знает. В частности я перерыл и библиотеки и интернет, но толком про передачу данных в DLL между паскалеподобными языками и всеми остальными ничего нет, хотя мысль заманчивая.

Вообще, братцы, кто-нибудь может прислать рабочий кусок исходника на Delphi, который пользуя через DLL процедуру СИ или Фортрана (исходник тоже шлите) скажем читает ссылку на описанный в Delphi массив, увеличивает его элементы на 1 (например) и возвращает ссылку на изменеммый массив.

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

Ну, удачи всем, KAS.

Автор: Hamster 27.6.2003, 02:35
Цитата(Fantasist @ 26.6.2003, 02:23)
Цитата
Но это только потому, что у меня небыло ещё ни одной книги по программированию


Книги книгами, но есть же help и есть соображаловка. smile.gif Желательно понимать, что ты такое написал и каким образом это работает. Потому как если просто тассовать выражение, пока хоть как-то не заработает, то вот на такие вещи и будешь напарываться - вроде работает, а делает что-то не то.

Без исходников dll тут наверняка сказать ничего нельзя. Попробуй изменить:
function test_read(p_type, port: Integer; var test: TEST_JOURNAL): Integer; cdecl;
external 'test.dll';

и сделать:

procedure TForm1.Button2Click(Sender: TObject);
begin
SetLength(data.operations,3);
test_read(2,2,data);
...
end;

Этот вариант пробовали с самого начала!

Автор: acp 27.6.2003, 04:32
Цитата
Кто пришлет, того я буду гением считать до конца жизни и в ножки поклонюсь.



Мне можно уже гнуть пальцы? wink.gif Спасибо...

Смотрим исходник.

http://port33.ru/users/acp/DLL_test.zip

Приложение с вызовом функции - Delphi + KOL.
DLL - asm (люблю я асм!).

PS: ах, да. Если вы посмотрите, то увидите, что я ещё люблю... компилить из командной строки smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)