OberonCore
https://forum.oberoncore.ru/

XDS и BlackBox
https://forum.oberoncore.ru/viewtopic.php?f=2&t=512
Страница 1 из 1

Автор:  PGR [ Вторник, 12 Июнь, 2007 10:52 ]
Заголовок сообщения:  XDS и BlackBox

При вызове Блэкбоксом функций из DLL-файла, скомпилированного XDS, идут ошибки при использовании в них динамической памяти.
У кого-нибудь есть опыт в работе BlackBox с XDS?

Автор:  Илья Ермаков [ Вторник, 12 Июнь, 2007 11:44 ]
Заголовок сообщения: 

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

Автор:  PGR [ Вторник, 12 Июнь, 2007 11:57 ]
Заголовок сообщения: 

Так если не использовать в XDS оператор NEW, то все отлично работает ...

Автор:  PGR [ Вторник, 12 Июнь, 2007 12:02 ]
Заголовок сообщения: 

Модуль 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 ]
Заголовок сообщения: 

Проблема однозначно в DLL. Если все собрано верно, то скорее всего, не выполняется какая-то необходимая инициализация. В документации XDS ничего не сказано относительно необходимости вызывать какую-то инициализационную функцию при начале использования DLL? (хотя есть стандартный способ для DLL инициализироваться при загрузке, но у него вроде бы есть некие недостатки, из-за которых они могли предпочесть явный вызов).
А из других языков/сред использовать DLL пробовали? Например, из Дельфы?

Автор:  PGR [ Вторник, 12 Июнь, 2007 14:35 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
В документации 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 ]
Заголовок сообщения: 

А какого рода ошибки идут? Как это проявляется?

Автор:  PGR [ Вторник, 12 Июнь, 2007 14:57 ]
Заголовок сообщения: 

Ошибка: NIL dereference (read) в StdInterpreter.CallProc.

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

Автор:  PGR [ Вторник, 12 Июнь, 2007 15:19 ]
Заголовок сообщения: 

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


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

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

Автор:  Илья Ермаков [ Вторник, 12 Июнь, 2007 16:04 ]
Заголовок сообщения: 

А, так бы и говорили, а я думал - пробовали XDS-DLL из Дельфи! :-)

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

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

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

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

Автор:  PGR [ Вторник, 12 Июнь, 2007 17:00 ]
Заголовок сообщения: 

В 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;

Автор:  PGR [ Вторник, 12 Июнь, 2007 22:44 ]
Заголовок сообщения: 

Разобрался.
В модуле нужно указать <*+MAIN*>, тогда можно работать с динамической памятью.
Если динамическая память не используется, то можно <*+MAIN*> и не указывать.
В документации об этом нигде явно не сказано :(

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

Автор:  Илья Ермаков [ Вторник, 12 Июнь, 2007 23:00 ]
Заголовок сообщения: 

Диспетчеры памяти не уживаются. А все из-за агрессивного хапания страниц у системы... С 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.

Автор:  PGR [ Среда, 13 Июнь, 2007 00:01 ]
Заголовок сообщения: 

На том массиве, где раньше вылетал, теперь при первом запуске нормально работает, при втором -- ругается illegal memory read, при третьем -- вылетает.
Но теперь даёт ошибку или вылетает на меньших массивах при каждом n-ном запуске.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/