OberonCore
https://forum.oberoncore.ru/

Интерфейсный модуль Free Pascal для модуля BlackBox
https://forum.oberoncore.ru/viewtopic.php?f=27&t=2307
Страница 1 из 1

Автор:  Роман М. [ Среда, 03 Февраль, 2010 16:50 ]
Заголовок сообщения:  Интерфейсный модуль Free Pascal для модуля BlackBox

Имеется проверочный модуль 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 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Почему работает Boolean, но не работает Files.Name?
Потому что у Boolean внутреннее представление простое до безобразия.
А вот у строки - сложное :)

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

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

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


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

Автор:  Роман М. [ Среда, 03 Февраль, 2010 17:16 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Тогда теперь вопрос такой: как, имея переменную path: INTEGER, работать со строкой, которую она представляет?

Автор:  Trurl [ Среда, 03 Февраль, 2010 17:37 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Код:
procedure foo(path: Pchar; path_len:Integer; name: Pchar; name_len:Integervar error: boolean);

Автор:  Евгений Темиргалеев [ Среда, 03 Февраль, 2010 18:48 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

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 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Я не понимаю почему нельзя экспортировать ARRAY OF CHAR? Ведь извне передаётся указатель на строку с нулевым символом. Строки совместимы. Разве не так?

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

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

Автор:  Илья Ермаков [ Четверг, 04 Февраль, 2010 16:00 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Общий принцип: вместо указателя на массив (* в Си) ставится VAR/IN/OUT. И используется ARRAY [untagged]. Или RECORD [untagged].

Автор:  Роман М. [ Четверг, 04 Февраль, 2010 16:06 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Так что-ли?

Экспорт из 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 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

вроде так

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

Автор:  Роман М. [ Четверг, 04 Февраль, 2010 16:36 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Код:
   TString* = ARRAY [untagged] OF CHAR;

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

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

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

Автор:  Илья Ермаков [ Четверг, 04 Февраль, 2010 16:41 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

IMPORT SYSTEM?

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

Автор:  Роман М. [ Четверг, 04 Февраль, 2010 16:52 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

Ну наконец-то! :lol:

Автор:  Роман М. [ Четверг, 04 Февраль, 2010 16:56 ]
Заголовок сообщения:  Re: Интерфейсный модуль Free Pascal для модуля BlackBox

И строки теперь понимает... Фух! Я, можно сказать, счастлив... до следующей проблемы.

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