OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 20 Август, 2019 02:17

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




Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
СообщениеДобавлено: Среда, 03 Февраль, 2010 16:50 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Имеется проверочный модуль TestExport, в котором экспортируются процедуры Foo, Foo2 и переменные.
Код:
PROCEDURE Foo* (IN path: Files.Name; name: Files.Name; OUT error: BOOLEAN);
PROCEDURE Foo2* (OUT error: BOOLEAN);

Определив в интерфейсной части описания этих процедур в Free Pascal
Код:
    TFooProc = procedure (path, name: Pchar; var error: boolean); stdcall;
    TFoo2Proc = procedure (var error: boolean); stdcall;
я получаю исключение при попытке выполнить процедуру Foo, однако, Foo2 выполняется гладко. DLL загружается динамически.
В Foo пробовал вместо Pchar выставить WideString, Array Of Char - не помогло.

Как правильно объявить Foo?

Код:
MODULE TestExport;

IMPORT Files;

TYPE
   TA* = RECORD
      d-,
      d2-: REAL;
   END;
   
VAR
   Int-: INTEGER;
   A-: TA;

PROCEDURE Foo* (IN path: Files.Name; name: Files.Name; OUT error: BOOLEAN);
BEGIN
   (*error := (name = "")*)
   error := TRUE
END Foo;

PROCEDURE Foo2* (OUT error: BOOLEAN);
BEGIN
   error := TRUE
END Foo2;

BEGIN
   A.d := 321.345;
   A.d2 := A.d*2.0;
   Int := 3*1024
END TestExport.

^Q DevLinker.LinkDll export.dll := Kernel+ Files TestExport# ~

Код:
Unit uexport;

Interface

Const

{$ifdef win32}
    Lib = 'export.dll';
  {$IFDEF FPC}
    {$smartlink on}
  {$ENDIF}
{$else}
    Lib = 'export.so';
{$endif}

type
    TA = record
        d,
        d2: double
    end;
    TFooProc = procedure (path, name: Pchar; var error: boolean); stdcall;
    TFoo2Proc = procedure (var error: boolean); stdcall;

Implementation

begin
end.


Код:
{$IFDEF FPC}
    {$mode delphi}
{$ENDIF}

program testexp;

uses
    HostModuleLoader, uexport;

var
    M: TDynLoadModule;
    pInt: pInteger;
    pA: ^TA;
    FooProc: TFooProc;
    Foo2Proc: TFoo2Proc;
    er: boolean;

begin
    M := TDynLoadModule.Create();
    if M.LoadModule (Lib) then
    begin
        writeln ('Loaded');
        pInt := M.GetModuleSymbol('Int');
        pA := M.GetModuleSymbol('A');
        @FooProc := M.GetModuleSymbol('Foo');
        @Foo2Proc := M.GetModuleSymbol('Foo2');

        if Assigned (pInt) then writeln (pInt^);
        if Assigned (pA) then begin
            writeln (pA^.d:8:2);
            writeln (pA^.d2:8:2);
        end;
        if Assigned (Foo2Proc) then begin
            writeln('Foo2 test');
            Foo2Proc (er);
            writeln (er);
        end;
        if Assigned (FooProc) then begin
            writeln('Foo test');
            FooProc ('', '', er);
            writeln (er);
        end;
       
        M.UnloadModule;
    end
    else writeln ('failed to load.');
    M.Free;
end.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Февраль, 2010 16:59 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Почему работает Boolean, но не работает Files.Name?
Потому что у Boolean внутреннее представление простое до безобразия.
А вот у строки - сложное :)

При переводе из среды в среду надо ориентироваться на то, что "честно" передать указатели и объекты не получится - слишком уж рантаймы разные. Поэтому, максимум, что можно сделать - это передавать машинные адреса (в смысле тот же PChar), сведенными к 32-х битному целому. Особенно, если мы проецируем внутренности ББ вовне.

Поэтому процедура Foo, скорее всего, должна выглядеть так:

Код:
PROCEDURE Foo* (IN path: INTEGER; name: INTEGER; OUT error: BOOLEAN);


и внутри нее из этого самого integer'а приведением получается адрес, указывающий на начало строки символов, которая используется в дальнейшем.
Вот как-то так...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Февраль, 2010 17:16 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Тогда теперь вопрос такой: как, имея переменную path: INTEGER, работать со строкой, которую она представляет?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Февраль, 2010 17:37 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1199
Код:
procedure foo(path: Pchar; path_len:Integer; name: Pchar; name_len:Integervar error: boolean);


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 03 Февраль, 2010 18:48 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4489
Откуда: Россия, Орёл
PChar <=> POINTER TO ARRAY [untagged] OF SHORTCHAR (если в FreePascal char-ы не двухбайтовые уже)
Trurl писал(а):
Код:
procedure foo(path: Pchar; path_len:Integer; name: Pchar; name_len:Integervar error: boolean);
Разве для статических массивов длина скрытым параметром передаётся? Также как и для открытых?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 15:47 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Я не понимаю почему нельзя экспортировать ARRAY OF CHAR? Ведь извне передаётся указатель на строку с нулевым символом. Строки совместимы. Разве не так?

Кто-то может ответить как передавать строки параметром в модуль ББ?
Неужели придётся заниматься извратом с трансляцией строка-указатель-целое число? В C/Free Pascal это ещё нормально, но вот в КП - небезопасно, кроме всего ещё и штатных средств нет.

Было бы неплохо, чтобы кто-то прояснил этот момент.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:00 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9129
Откуда: Россия, Орёл
Общий принцип: вместо указателя на массив (* в Си) ставится VAR/IN/OUT. И используется ARRAY [untagged]. Или RECORD [untagged].


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:06 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Так что-ли?

Экспорт из BlackBox
Код:
PROCEDURE Foo* (IN path, name: ARRAY [untagged] OF CHAR; OUT error: BOOLEAN);


Импорт в Free Pascal
Код:
    TFooProc = procedure (path, name: pchar; var error: boolean); stdcall;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:08 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9129
Откуда: Россия, Орёл
вроде так

насчёт BOOLEAN надо быть осторожным тоже при межъязыковой работе. Размер и проч. TRUE = 1 или #0...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:36 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Код:
   TString* = ARRAY [untagged] OF CHAR;

Пишет, illegal sys flag перед "untagged".

Загадочно получается... :?

Код:
PROCEDURE Foo* (IN path, name: TString; OUT error: BOOLEAN);


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:41 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9129
Откуда: Россия, Орёл
IMPORT SYSTEM?

У меня всё копилируется.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:52 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
Ну наконец-то! :lol:


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 04 Февраль, 2010 16:56 
Аватара пользователя

Зарегистрирован: Пятница, 25 Сентябрь, 2009 13:10
Сообщения: 1162
Откуда: Tel-Aviv
И строки теперь понимает... Фух! Я, можно сказать, счастлив... до следующей проблемы.


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

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


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

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


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

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