OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 20 Апрель, 2021 07:54

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
 Заголовок сообщения: XDS и BlackBox
СообщениеДобавлено: Вторник, 12 Июнь, 2007 10:52 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
При вызове Блэкбоксом функций из DLL-файла, скомпилированного XDS, идут ошибки при использовании в них динамической памяти.
У кого-нибудь есть опыт в работе BlackBox с XDS?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 11:44 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9402
Откуда: Россия, Орёл
Вообще говоря, 1) если DLL XDS собрана правильно, то ей все равно, откуда ее используют.
С другой стороны, 2) Блэкбоксу тоже глубоко все равно, чью DLL использовать.
Значит, если 1) соблюдено, то дело в том, КАК организовано взаимодействие и что туда передается. Нужен контекст - что и как вызываете...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 11:57 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Так если не использовать в XDS оператор NEW, то все отлично работает ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 12:02 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Модуль Test.ob2
Код:
MODULE Test;

TYPE
  INTEGER = LONGINT;
  REAL = LONGREAL;

PROCEDURE ["StdCall"] Sum*(n: INTEGER): REAL;
VAR a: POINTER TO ARRAY OF REAL; i: INTEGER; s: REAL;
BEGIN
  NEW(a, n);
  FOR i := 0 TO n-1 DO a[i] := i; END;
  s := 0;
  FOR i := 0 TO n-1 DO s := s + a[i]; END;
  RETURN s;
END Sum;

END Test.


Проект XDS
Код:
-gendll+
-dllexport+
-o2extensions+
!module Test.ob2


Модуль импорта BlackBox
Код:
MODULE XdsTest ["Test.dll"];
  PROCEDURE Sum* (n: INTEGER): REAL;
END XdsTest.


Модуль использования
Код:
MODULE XdsUse;
  IMPORT Xds := XdsTest, Log;

  PROCEDURE Do*;
  BEGIN
    Log.Real(Xds.Sum(10));
  END Do;

END XdsUse.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 12:58 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9402
Откуда: Россия, Орёл
Проблема однозначно в DLL. Если все собрано верно, то скорее всего, не выполняется какая-то необходимая инициализация. В документации XDS ничего не сказано относительно необходимости вызывать какую-то инициализационную функцию при начале использования DLL? (хотя есть стандартный способ для DLL инициализироваться при загрузке, но у него вроде бы есть некие недостатки, из-за которых они могли предпочесть явный вызов).
А из других языков/сред использовать DLL пробовали? Например, из Дельфы?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 14:35 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Илья Ермаков писал(а):
В документации XDS ничего не сказано относительно необходимости вызывать какую-то инициализационную функцию при начале использования DLL?


XDS Help писал(а):
The default XDS DLL startup code performs all the actions required for the DLL to function properly in the XDS run-time environment.


Илья Ермаков писал(а):
А из других языков/сред использовать DLL пробовали? Например, из Дельфы?


Попробовал в Delphi. Работает...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 14:47 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9402
Откуда: Россия, Орёл
А какого рода ошибки идут? Как это проявляется?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 14:57 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Ошибка: NIL dereference (read) в StdInterpreter.CallProc.

Попробовал вызывать эту DLL из сишной программы -- тоже вылетает с ошибкой. Такчто проблема с XDS, а не BlackBox.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 15:19 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
PGR писал(а):
Илья Ермаков писал(а):
А из других языков/сред использовать DLL пробовали? Например, из Дельфы?


Попробовал в Delphi. Работает...

В смысле попробовал аналогичную DLL, созданную в Delphi, вызывать из BlackBox.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 16:04 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9402
Откуда: Россия, Орёл
А, так бы и говорили, а я думал - пробовали XDS-DLL из Дельфи! :-)

Если NIL dereference (READ), то это значит, что функция с таким именем в DLL не найдена - и указатель на точку входа в нее нулевой.

Возможно, здесь проблема с именованием процедуры. Для StdCall-DLL есть соглашение о том, что имя, под которым экспортируется, "коверкается" суффиксом @размер_параметров_в_байтах.

Но Блэкбокс должен бы это учитывать... Ведь в исходнике WinApi явно имена с @ не указываются. Или может быть, API-функции не имеют этого суффикса?
Или наоборот - ББ учитывает, а вот XDS не добавляет суффикса?

Попробуйте посмотреть таблицу экспорта DLL каким-нибудь PE-браузером. Или даже проще всего - ФАРом, найдите имя вашей процедуры - есть там собачка в конце с числом?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 17:00 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
В Dependency Walker имя функции "Sum" без всяких значков.
Тут дело, кажется, не в этом. Если в функции не использовать динамический массив, то всё работает.
Код:
PROCEDURE ["StdCall"] Sum*(n: INTEGER): REAL;
VAR a: ARRAY 50 OF REAL; i: INTEGER; s: REAL;
BEGIN
  FOR i := 0 TO n-1 DO a[i] := i; END;
  s := 0;
  FOR i := 0 TO n-1 DO s := s + a[i]; END;
  RETURN s;
END Sum;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 22:44 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Разобрался.
В модуле нужно указать <*+MAIN*>, тогда можно работать с динамической памятью.
Если динамическая память не используется, то можно <*+MAIN*> и не указывать.
В документации об этом нигде явно не сказано :(

Продолжение проблемы...
Если использовать достаточно большие динамические массивы, то приходится вручную
вызывать сборщик мусора oberonRTS.Collect, иначе после нескольких запусков
через коммандер BlackBox вылетает без каких-либо сообщений.
А при ещё больших массивах BlackBox вылетает и при первом запуске :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 23:00 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9402
Откуда: Россия, Орёл
Диспетчеры памяти не уживаются. А все из-за агрессивного хапания страниц у системы... С XDS могли не поладить, потому что Блэкбокс в начале работы вообще резервирует себе почти все пространство адресов... А XDS в остатки не вмещается.

Однако диспетчер Блэкбокса может работать в двух режимах - в буйном (по умолчанию) и в мирном (когда он сам внутри DLL). Так вот, можно форсировать второй режим - перекомпилируйте Kernel, заменив в нем в секции инициализации
Код:
BEGIN
   IF modList = NIL THEN   (* only once *)
      S.GETREG(ML, modList);   (* linker loads module list to BX *)
      S.GETREG(SP, baseStack);
      static := init IN modList.opts;
      inDll := dll IN modList.opts; dllMem := inDll;

"dllMem := inDll" на "dllMem := TRUE".

Возможно, после этого они сживутся с XDS.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 00:01 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
На том массиве, где раньше вылетал, теперь при первом запуске нормально работает, при втором -- ругается illegal memory read, при третьем -- вылетает.
Но теперь даёт ошибку или вылетает на меньших массивах при каждом n-ном запуске.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 3 часа


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2021, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB