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/ |