На главную Наши проекты:
Журнал   ·   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_
  
> Помогите подписаться на события DLL
    Помогите, я окончательно запутался. Опыт работы в Delphi небольшой...
    Использую DLL от китайского оборудования, необходимо подписаться на события, которые он генерирует.

    В .H файле функция описана так

    ExpandedWrap disabled
      typedef void (* DECODE_NOTIFY_CALLBACK)(void *buf, DWORD DataLen);
       
      FSC_API int __stdcall EnableDecodeNotify(HCONNECT hConnect, HANDLE hWnd, DWORD Option, void *Buffer, DWORD BufferSize, DECODE_NOTIFY_CALLBACK callback);



    Пишу на Delphi, даже не компилируется :(

    ExpandedWrap disabled
      type
        TDecodeNotify = procedure(Buffer:PChar;Size:integer); stdcall;
       
      ......
       
       TMyClass = class(TV8UserObject)
        private
          procedure DecodeNotify(Buffer: PChar; Size:integer); stdcall;
       
      ......
       
       
      // Реализация события
      procedure TMyClass.DecodeNotify(Buffer: PChar; Size:integer);
      var
        Module, Event, Data: PWideChar;
        ResStr: ansistring;
      begin
        Module := PWideChar('Hardware');
        Event := PWideChar('Scan');
       
        if Size>0 then SetString(ResStr, Buffer, Size)
        else ResStr := '';
       
        Data := PWideChar(ResStr);
       
        V8.ExternalEvent(Module, Event, Data);
       
      end;
       
      ......
       
      // Нерабочая попытка подписаться на события
      function TMyClass.SearchCOMA(RetValue: PV8Variant; Params: PV8ParamArray;  const ParamCount: integer; var v8:TV8AddInDefBase): boolean;
      var
        ScanerID: integer;
        FunctionDLL:TSearchCOMW;
        FunctionDLL2:TEnableDecodeNotify;
      begin
      ........
       
        ScanerID:= FunctionDLL(ComPort); { используем ф-ию }
       
        if ScanerID <> -1 then begin
          @FunctionDLL2 := GetProcAddress(HandleDLL, '_EnableDecodeNotify@24');
          Assert(@FunctionDLL2 <> nil);
       
          FunctionDLL2(ScanerID,0,0,Addr(Buffer),SizeOf(Buffer),DecodeNotify);  // <= Тут ошибка  
      // [dcc32 Error] cino1.pas(159): E2009 Incompatible types: 'regular procedure and method pointer'
        end;
       
      end;


    Что я делаю не так ??? Как правильно подписаться на событие DLL ?
      Цитата tiger1c @
      Что я делаю не так ???

      В сообщении об ошибке все сказано: несмотря на видимое одинаковое объявление параметров обычная процедура и метод класса являются несовместимыми процедурными типами (т.к. на самом деле любой метод класса имеет дополнительный скрытый параметр - указатель Self). Соотв-но эти типы и объявляются по разному:
      ExpandedWrap disabled
        type
          TDecodeNotifyProc = procedure(Buffer:PChar;Size:integer); stdcall;  //обычная процедура
          TDecodeNotifyMethod = procedure(Buffer:PChar;Size:integer) of object; stdcall;  //метод класса


      Цитата tiger1c @
      Как правильно подписаться на событие DLL ?

      Объявить DecodeNotify как обычную процедуру, а не метод класса.
        В сообщении же написано - коллбэк процедура должна быть простой процедурой, а не методом объекта.

        ExpandedWrap disabled
            procedure DecodeNotify(Buffer: PChar; Size: DWord); stdcall;
            var
             ...


        Кроме того, манипуляции внутри процедуры с кастингом ansistring к PWideChar могут быть сомнительными
        Сообщение отредактировано: MBo -
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0294 ]   [ 17 queries used ]   [ Generated: 20.04.24, 05:02 GMT ]