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