На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

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


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> использование tom.dll , как?
    один знакомый написал русский парсер, и оформил его в виде dll. ну, т е у него есть какая-то демка и игра, оболочка и т п,
    НО
    меня интересует именно dll. и именно использование её на Delphi. к сожалению, он пишет на Си, и не может мне толком помочь. вот мой с ним диалог:

    noname
    Цитата
    отсюда вопрос: как прикрутить tom.dll к моей проге?

    ASBer
    Цитата
    На Си я это делаю так:

    Глобальные переменные:
    ExpandedWrap disabled
      //переменные для текстового движка
      HINSTANCE EngineDll;
      typedef char*(*EngineFn)(char*);
      EngineFn RunFile=0;
      EngineFn RunText=0;
      EngineFn Command=0;
      EngineFn NormText=0;

    При старте программы:
    ExpandedWrap disabled
        //загружаем движок
        EngineDll=GetModuleHandle("tom.dll");
        if(!EngineDll) EngineDll=LoadLibrary("tom.dll");
        if(!EngineDll)
        { PutStr("<font color=red>Не удалось загрузить tom.dll!\n<pause>");
          return 0;
        }
        //получаем функции
        RunFile=(EngineFn)GetProcAddress(EngineDll,"@RunFile$qpc");
        RunText=(EngineFn)GetProcAddress(EngineDll,"@RunText$qpc");
        Command=(EngineFn)GetProcAddress(EngineDll,"@Command$qpc");
        NormText=(EngineFn)GetProcAddress(EngineDll,"@NormText$qpc");
       
        if(!RunFile||!RunText||!Command||!NormText)
        { PutStr("<font color=red>Не найдены функции tom.dll!\n<pause>");
          return 0;
        }

    в процессе:
    ExpandedWrap disabled
      char*Str=Command(input);

    при закрытии программы:
    ExpandedWrap disabled
        //освобождаем движок
        FreeLibrary(EngineDll);

    GetModuleHandle(), LoadLibrary(), GetProcAddress(), FreeLibrary() - функции WinAPI.

    На паскале никогда не писал, тут я не помощник... hmm


    я, блин, и на Delphi-то не очень, а понять что здесь написано, и использовать tom.dll в своей проге- тем более сложно. там всего-то одно окно да один edit.

    уже имеющиеся под ТОМ оболочки меня не устраивают: одна из них- досовское текстовое окошко, с другой чё-та сильно заморочено. другую писал другой автор для своего движка, и сделал заодно возможность использовать ТОМ.

    ---
    ну, короче, думаю, суть вопроса ясна.
      Цитата ya2500 @
      char*Str=Command(input);

      Угу. Насколько я понимаю, все функции возвращают строку. Здесь сразу проблема в освобождении выделенной памяти. Можешь попросить его экспортировать еще и функцию вроде Free_it, которая просто освобождает выделенную под результат функции память?
      Иначе будут проблемы ;)
        Пускай он тебе пропишет функции конкретно
        например

        ExpandedWrap disabled
          longInt GetMyAIstartAlianse(int AlianseIndex, bool InCurrentProcess);


        А ты в делфе
        ExpandedWrap disabled
          Function  GetMyAIstartAlianse(AlianseIndex:integer;InCurrentProcess:boolean):LONGINT;cdecl;stdcall; external 'DrugLIB.dll';

        И примерно вв таком темпе эзайте функции.

        Пускай он тебе отдельно пропишет каждую функции по шаблону WIN32.API
        GetXXXXXXXX
        SetXXXXXXXX


        Добавлено
        //переменные для текстового движка

        typedef char*(*EngineFn)(char*);

        На Делфи
        ExpandedWrap disabled
          type
          TEngineFn = integer;{или POINTER но нужно дорабатывать}
           
          var
          EngineDll: HINSTANCE;
          RunFile: TEngineFn =0;
          Command: TEngineFn  =0;
          NormText: TEngineFn  =0;


        В случае {или POINTER} тебе нужно будет ассигновать тип с реально существующим классом.
        Но проблема в:
        Цитата ya2500 @
        я, блин, и на Delphi-то не очень, а понять что здесь написано, и использовать tom.dll


        По этому используй метод который я тебе описал выше.
        Сообщение отредактировано: aster_x -
          Цитата aster_x @
          Пускай он тебе пропишет функции конкретно


          Цитата aster_x @
          typedef char*(*EngineFn)(char*);

          На Делфи
          type
          TEngineFn = pointer;

          Вот не надо. Все функции описаны. И описаны совсем не так, а как функция с одним параметром PChar возвращающая PChar.
          Единственный вопрос что делать с результатом функции после его использования, для этого просто нужен экспорт еще одной функции примерно как void free_it(char*);
            Romkin++
              Цитата Romkin @
              Угу. Насколько я понимаю, все функции возвращают строку. Здесь сразу проблема в освобождении выделенной памяти. Можешь попросить его экспортировать еще и функцию вроде Free_it, которая просто освобождает выделенную под результат функции память?
              Иначе будут проблемы

              Цитата Romkin @
              Единственный вопрос что делать с результатом функции после его использования, для этого просто нужен экспорт еще одной функции примерно как void free_it(char*);

              хорошо. я дам ему ссылку на эту тему, надеюсь он поймёт, что от него требуется.

              допустим, у меня простое приложение с одним едитом и одним мемо. я хочу строку с едита передать на обработку этой длл-ке, а результат поместить в мемо. и, собственно, простейшая оболочка- готова. дальше можно совершенствовать это дело как угодно.

              вопрос такой: что на Delphi будет соответствовать коду
              ExpandedWrap disabled
                //переменные для текстового движка
                HINSTANCE EngineDll;
                typedef char*(*EngineFn)(char*);
                EngineFn RunFile=0;
                EngineFn RunText=0;
                EngineFn Command=0;
                EngineFn NormText=0;
              ну, и так далее. я просто не могу понять сишного синтаксиса.
              ---
              всё, пошёл давать ему ссылку.

              Добавлено
              Цитата Romkin @
              Вот не надо. Все функции описаны. И описаны совсем не так, а как функция с одним параметром PChar возвращающая PChar.
              кажется, в теме УЖЕ содержится ответ. осталось только его понять. буду думать.
                Цитата ya2500 @
                вопрос такой: что на Delphi будет соответствовать коду

                ExpandedWrap disabled
                  HINSTANCE EngineDll; // это хэндл (беззнаковое целое, т.е. обычный Cardinal), в Delphi описан как THandle
                  typedef char*(*EngineFn)(char*); // это указатель на функцию (простую, не метод!), возвращающую PChar и принимающую как параметр тоже PChar, в Delphi решается как-то так: TEngineFn = function(arg: PChar): PChar;
                  // дальше просто конкретные переменные, хранящие указатели на конкретные функции с такой сигнатурой
                  EngineFn RunFile=0;
                  EngineFn RunText=0;
                  EngineFn Command=0;
                  EngineFn NormText=0;


                смотри комментарии в коде
                  Цитата Romkin @
                  Цитата (ya2500 @ Вчера, 17:03)
                  char*Str=Command(input);

                  Угу. Насколько я понимаю, все функции возвращают строку. Здесь сразу проблема в освобождении выделенной памяти. Можешь попросить его экспортировать еще и функцию вроде Free_it, которая просто освобождает выделенную под результат функции память?
                  Иначе будут проблемы


                  Освобождение выделенной памяти происходит при следующем вызове функций движка. Или при освобождении dll.
                  Подразумевается что при следующем вызове функции результаты предыдущего вызова вам уже не нужны.
                    Цитата ASBer @
                    Освобождение выделенной памяти происходит при следующем вызове функций движка. Или при освобождении dll.
                    Подразумевается что при следующем вызове функции результаты предыдущего вызова вам уже не нужны.

                    Интересный подход.

                    ya2500, могу предложить использовать это в Делфи таким образом:
                    ExpandedWrap disabled
                      unit UTom;
                       
                      interface
                       
                      uses
                        Windows, SysUtils;
                       
                      type
                        TTomFunc = function(P: PAnsiChar): PAnsiChar; cdecl;
                       
                        ETomWrapperError = class(Exception);
                        TTomWrapper = class(TObject)
                        protected
                          FHLibrary:  HMODULE;
                          FRunFile:   TTomFunc;
                          FRunText:   TTomFunc;
                          FCommand:   TTomFunc;
                          FNormText:  TTomFunc;
                          function CallTomFunc(Func: TTomFunc; const Input: string): string;
                        public
                          constructor Create(const LibName: string = '');
                          destructor Destroy(); override;
                          function RunFile(const Input: string): string;
                          function RunText(const Input: string): string;
                          function Command(const Input: string): string;
                          function NormText(const Input: string): string;
                        end;
                       
                      implementation
                       
                      resourcestring
                        STomDllDefFilename  = 'Tom.dll';
                       
                        SRunFileFuncName    = '@RunFile$qpc';
                        SRunTextFuncName    = '@RunText$qpc';
                        SCommandFuncName    = '@Command$qpc';
                        SNormTextFuncName   = '@NormText$qpc';
                       
                        SErrorLoadLibrary   = 'Не удалось загрузить библиотеку "%s", ошибка %d';
                        SErrorGetFunctions  = 'Не удалось найти функции бибилиотеки';
                       
                      { TTomWrapper }
                       
                      constructor TTomWrapper.Create(const LibName: string);
                      var
                        TomFilename: string;
                      begin
                        inherited Create();
                        if (LibName <> '') then
                          TomFilename := LibName
                        else
                          TomFilename := STomDllDefFilename;
                        FHLibrary := LoadLibrary(PChar(TomFilename));
                        if (FHLibrary = 0) then
                          raise ETomWrapperError.CreateFmt(SErrorLoadLibrary, [TomFilename, GetLastError()]);
                        FRunFile  := TTomFunc(GetProcAddress(FHLibrary, PChar(SRunFileFuncName)));
                        FRunText  := TTomFunc(GetProcAddress(FHLibrary, PChar(SRunTextFuncName)));
                        FCommand  := TTomFunc(GetProcAddress(FHLibrary, PChar(SCommandFuncName)));
                        FNormText := TTomFunc(GetProcAddress(FHLibrary, PChar(SNormTextFuncName)));
                        if ((@FRunFile = nil) or (@FRunText = nil) or (@FCommand = nil) or (@FNormText = nil)) then
                          raise ETomWrapperError.Create(SErrorGetFunctions);
                      end;
                       
                      destructor TTomWrapper.Destroy();
                      begin
                        if (FHLibrary <> 0) then
                          FreeLibrary(FHLibrary);
                        inherited Destroy();
                      end;
                       
                      function TTomWrapper.CallTomFunc(Func: TTomFunc; const Input: string): string;
                      var
                        AnsiStr: AnsiString;
                      begin
                        Result := '';
                        if (@Func <> nil) then
                        begin
                          AnsiStr := AnsiString(Input);
                          UniqueString(AnsiStr);
                          AnsiStr := Func(PAnsiChar(AnsiStr));
                          Result := string(AnsiStr);
                        end;
                      end;
                       
                      function TTomWrapper.RunFile(const Input: string): string;
                      begin
                        Result := CallTomFunc(FRunFile, Input);
                      end;
                       
                      function TTomWrapper.RunText(const Input: string): string;
                      begin
                        Result := CallTomFunc(FRunText, Input);
                      end;
                       
                      function TTomWrapper.Command(const Input: string): string;
                      begin
                        Result := CallTomFunc(FCommand, Input);
                      end;
                       
                      function TTomWrapper.NormText(const Input: string): string;
                      begin
                        Result := CallTomFunc(FNormText, Input);
                      end;
                       
                      end.

                    Применять например так:
                    ExpandedWrap disabled
                      unit Unit1;
                       
                      interface
                       
                      uses
                        Windows, SysUtils, Classes, Graphics, Controls, StdCtrls, Forms,
                        UTom;
                       
                      type
                        TForm1 = class(TForm)
                          Edit1: TEdit;
                          Button1: TButton;
                          Label1: TLabel;
                          procedure FormDestroy(Sender: TObject);
                          procedure FormActivate(Sender: TObject);
                          procedure Button1Click(Sender: TObject);
                        private
                          { Private declarations }
                          Tom: TTomWrapper;
                        public
                          { Public declarations }
                        end;
                       
                      var
                        Form1: TForm1;
                       
                      implementation
                       
                      {$R *.dfm}
                       
                      procedure TForm1.FormActivate(Sender: TObject);
                      begin
                        Tom := TTomWrapper.Create();
                      end;
                       
                      procedure TForm1.FormDestroy(Sender: TObject);
                      begin
                        Tom.Free();
                      end;
                       
                      procedure TForm1.Button1Click(Sender: TObject);
                      begin
                        Label1.Caption := 'Tom returns: "' + Tom.NormText(Edit1.Text) + '"';//например, NormText()
                      end;
                       
                      end.

                    Естественно не проверял, но где-то в этом духе.
                    Сообщение отредактировано: arj99 -
                      Romkin, Mr.Delphist - спасибо. кажется, я начинаю понимать.

                      короче, чтоб юзать эту dll нужно:
                      - задать (указатели на?) 4-ре функции. у каждой и параметр и возвращаемое значение- указатель на строку(типа того).
                      - загрузить dll. думаю, разберусь, как это делается на Delphi.
                      - получить функции. т е - указатели на них.
                      - как пользоваться этими функциями- разбораться не проблема. лишь бы разобраться в предыдущих пунктах.

                      пока буду курить хелпы. галочку "вопрос решён" поставлю после того, как сделаю простейшую прогу, с использованием tom.dll.

                      сейчас мне осталось разобраться с:
                      - хэндлами и функциями, которые можно получить по указателю. (может занять какое-то время)
                      - и загрузкой dll. (это должно быть элементарно)

                      Добавлено
                      arj99, ой тока увидел. щазз почитаю
                        Цитата Romkin @
                        Вот не надо. Все функции описаны. И описаны совсем не так, а как функция с одним параметром PChar возвращающая PChar.

                        Совершенно верно. Это обычные функции (не методы). В исходниках движка выглядят примерно так:
                        ExpandedWrap disabled
                          __declspec(dllexport) char*Command(char*Input)
                          { char*Result;
                            ...
                            return Result;
                          }
                          ya2500, забыл заметить - это набросок на скорую руку для Ansi-версий Делфи.
                          Сообщение отредактировано: arj99 -
                            Самое простенькое просто присоединить библиотеку, сделав небольшие обертки. Правда, библиотека будет висеть постоянно:
                            ExpandedWrap disabled
                              unit TomLib;
                               
                              interface
                               
                              uses SysUtils;
                               
                              function RunFile(const FileStr: AnsiString): AnsiString;
                              function RunText(const TextStr: AnsiString): AnsiString;
                              function Command(const CommandStr: AnsiString): AnsiString;
                              function NormText(const TextStr: AnsiString): AnsiString;
                               
                              implementation
                               
                              const
                                TomLibName = 'tom.dll';
                               
                              function TomRunFile(Str: PAnsiChar): PAnsiChar; cdecl;
                                external TomLibName name '@RunFile$qpc';
                              function TomRunText(Str: PAnsiChar): PAnsiChar; cdecl;
                                external TomLibName name '@RunText$qpc';
                              function TomCommand(Str: PAnsiChar): PAnsiChar; cdecl;
                                external TomLibName name '@Command$qpc';
                              function TomNormText(Str: PAnsiChar): PAnsiChar; cdecl;
                                external TomLibName name '@NormText$qpc';
                               
                              function RunFile(const FileStr: AnsiString): AnsiString;
                              var
                                Str: AnsiString;
                              begin
                                //На всякий случай полная копия параметра
                                Str := FileStr;
                                UniqueString(Str);
                                //Здесь копирование идет
                                Result := TomRunFile(PAnsiChar(Str));
                                assert(Str = FileStr);
                              end;
                               
                              function RunText(const TextStr: AnsiString): AnsiString;
                              var
                                Str: AnsiString;
                              begin
                                Str := TextStr;
                                UniqueString(Str);
                                Result := TomRunFile(PAnsiChar(Str));
                                assert(Str = TextStr);
                              end;
                               
                              function Command(const CommandStr: AnsiString): AnsiString;
                              var
                                Str: AnsiString;
                              begin
                                Str := CommandStr;
                                UniqueString(Str);
                                Result := TomCommand(PAnsiChar(Str));
                                assert(Str = CommandStr);
                              end;
                               
                              function NormText(const TextStr: AnsiString): AnsiString;
                              var
                                Str: AnsiString;
                              begin
                                Str := TextStr;
                                UniqueString(Str);
                                Result := TomNormText(PAnsiChar(Str));
                                assert(Str = TextStr);
                              end;
                               
                              end.


                            Цитата ASBer @
                            Освобождение выделенной памяти происходит при следующем вызове функций движка. Или при освобождении dll.

                            Действительно оригинально :)
                              Romkin опытный аксакал :) полностью скопировать строку я не подумал, а стоило бы.
                              Исправил UTom с этим дополнением в сообщении #9, теперь он вроде даже Unicode-ready.
                              Сообщение отредактировано: arj99 -
                                А вот что буквально написано в первом топике, врапперы оставил:
                                ExpandedWrap disabled
                                  unit TomLib;
                                   
                                  interface
                                   
                                  uses Windows, SysUtils;
                                   
                                  type
                                    ETomError = class(Exception);
                                   
                                  function RunFile(const FileStr: AnsiString): AnsiString;
                                  function RunText(const TextStr: AnsiString): AnsiString;
                                  function Command(const CommandStr: AnsiString): AnsiString;
                                  function NormText(const TextStr: AnsiString): AnsiString;
                                   
                                  implementation
                                   
                                  const
                                    TomLibName = 'tom.dll';
                                   
                                  type
                                    TomFunc = function(Str: PAnsiChar): PAnsiChar; cdecl;
                                   
                                  var
                                    TomLibHandle: HMODULE;
                                    TomRunFile: TomFunc = nil;
                                    TomRunText: TomFunc = nil;
                                    TomCommand: TomFunc = nil;
                                    TomNormText: TomFunc = nil;
                                   
                                  procedure InitTomLib;
                                  begin
                                    TomLibHandle := LoadLibrary(TomLibName);
                                    if TomLibHandle = 0 then
                                      raiseLastOSError;
                                    TomRunFile:= GetProcAddress(TomLibHandle, '@RunFile$qpc');
                                    if not assigned(TomRunFile) then
                                      raiseLastOSError;
                                    TomRunText:= GetProcAddress(TomLibHandle, '@RunText$qpc');
                                    if not assigned(TomRunText) then
                                      raiseLastOSError;
                                    TomCommand:= GetProcAddress(TomLibHandle, '@Command$qpc');
                                    if not assigned(TomCommand) then
                                      raiseLastOSError;
                                    TomNormText:= GetProcAddress(TomLibHandle, '@NormText$qpc');
                                    if not assigned(TomNormText) then
                                      raiseLastOSError;
                                  end;
                                   
                                  procedure UnloadTomLib;
                                  begin
                                    if TomLibHandle = 0 then
                                      FreeLibrary(TomLibHandle);
                                  end;
                                   
                                  procedure CheckFunc(Func: TomFunc);
                                  begin
                                    if not assigned(Func) then
                                      raise ETomError.Create('Функция недоступна');
                                  end;
                                   
                                  function RunFile(const FileStr: AnsiString): AnsiString;
                                  var
                                    Str: AnsiString;
                                  begin
                                    //На всякий случай полная копия параметра
                                    Str := FileStr;
                                    UniqueString(Str);
                                    //Здесь копирование
                                    CheckFunc(TomRunFile);
                                    Result := TomRunFile(PAnsiChar(Str));
                                    assert(Str = FileStr);
                                  end;
                                   
                                  function RunText(const TextStr: AnsiString): AnsiString;
                                  var
                                    Str: AnsiString;
                                  begin
                                    //На всякий случай полная копия параметра
                                    Str := TextStr;
                                    UniqueString(Str);
                                    //Здесь копирование
                                    CheckFunc(TomRunText);
                                    Result := TomRunText(PAnsiChar(Str));
                                    assert(Str = TextStr);
                                  end;
                                   
                                  function Command(const CommandStr: AnsiString): AnsiString;
                                  var
                                    Str: AnsiString;
                                  begin
                                    //На всякий случай полная копия параметра
                                    Str := CommandStr;
                                    UniqueString(Str);
                                    //Здесь копирование
                                    CheckFunc(TomCommand);
                                    Result := TomCommand(PAnsiChar(Str));
                                    assert(Str = CommandStr);
                                  end;
                                   
                                  function NormText(const TextStr: AnsiString): AnsiString;
                                  var
                                    Str: AnsiString;
                                  begin
                                    //На всякий случай полная копия параметра
                                    Str := TextStr;
                                    UniqueString(Str);
                                    //Здесь копирование
                                    CheckFunc(TomNormText);
                                    Result := TomNormText(PAnsiChar(Str));
                                    assert(Str = TextStr);
                                  end;
                                   
                                   
                                  initialization
                                    InitTomLib;
                                   
                                  finalization
                                    UnloadTomLib;
                                   
                                  end.

                                Ну понятно, если хочется грузить когда надо, то просто выставить InitTomLib и UnloadTomLib в интерфейс, и защита нужна.

                                Добавлено
                                Цитата arj99 @
                                Исправил UTom с этим дополнением в сообщении #9, теперь он вроде даже Unicode-ready.

                                CallTomFunc:
                                в 80й строке ошибка, PAnsiChar нужен вместо PChar.
                                А во-вторых, смысла особого не имеет подавать юникод, лучше просто оформить все в ansi. Оно все равно преобразуется в него при вызове.
                                [DCC Warning] UTom.pas(78): W1058 Implicit string cast with potential data loss from 'string' to 'AnsiString'
                                [DCC Warning] UTom.pas(81): W1057 Implicit string cast from 'AnsiString' to 'string'
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0606 ]   [ 16 queries used ]   [ Generated: 19.04.24, 21:06 GMT ]