Конференция "Начинающим" » Не работает Callback из DLL [D2005, XP]
 
  • Tiger (16.10.17 22:19) [0]
    Использую чужую DLL написанная на С

    Описание функции:

    int __stdcall EnableDecodeNotify (HCONNECT hConnect, HANDLE hWnd, DWORD Option, void *Buffer, DWORD BufferSize, DECODE_NOTIFY_CALLBACK callback);



    Пишу в Delphi так


    TDecodeNotify = procedure(Buffer:PAnsiChar;Size:longword) of object; stdcall;

     TMyClass = class(TV8UserObject)
     private
       Buffer: array[0..1023] of char;

       procedure MyDecodeNotify(Buffer: PAnsiChar; Size:longword); stdcall;
    .....
      end;

    implementation

     function FSC_EnableDecodeNotify (hConnect: integer; hWnd: THandle;Option: longword; Buffer: Pointer; BufferSize: longword; callback: TDecodeNotify):integer; stdcall; external  'FSC.DLL' name '_EnableDecodeNotify';




    Инциализирую так:

      DebugInt:=FSC_EnableDecodeNotify(hConnect, 0, Option, @Buffer, SizeIF(Buffer), MyDecodeNotify);



    И не работает - Callback не вызывается
  • Tiger (16.10.17 22:51) [1]
    Подозреваю такие варианты:

    1. Неправильно перевел синтаксис процедуры из С
    2. Неправильно передаю адрес процедуры Callback
    3. Нельзя использовать Callback-процедуру в объекте
    4. Для вызова Callback нужны дополнительные действия.

    Есть пример на С и VB в котором Callback работает
  • Dimka Maslov © (16.10.17 23:11) [2]
    Функции обратного вызова нельзя объявлять как члены класса, ибо в них неявно передаётся указатель на объект.  
    Надо объявлять только так:

    TDecodeNotify = procedure (Buffer: PAnsiChar; Size: DWORD);

    procedure DecodeNotify(Buffer: PAnsiChar; Size: DWORD);
    begin
    ....
    end;

    DebugInt:=FSC_EnableDecodeNotify(hConnect, 0, Option, @Buffer, SizeOf(Buffer), DecodeNotify);
  • Tiger (16.10.17 23:41) [3]
    1. Не помогло - callback так и не отрабатывается :(

    2. Как можно обойти ограничение? В объекте есть данные которые нужны для дальнейшей обработки события.
  • rrrrrr © (16.10.17 23:50) [4]
    int EnableDecodeNotify(......

    смотри что она тебе вернула и кури коды ошибок в доке к длл
  • rrrrrr © (16.10.17 23:57) [5]
    Как можно обойти ограничение?

    Option: longword

    сам колбек делаем отдельно-стоящим, а через option передаем ссылку на объект
    когда исправишь ошибки, объект к тебе прилетит в вызов колбэка.
  • rrrrrr © (17.10.17 00:03) [6]
    плюс не видно оригинального прототипа для DECODE_NOTIFY_CALLBACK

    я не думаю что он вот такой вот
    procedure MyDecodeNotify(Buffer: PAnsiChar; Size:longword); stdcall;

    в православном правильном колбэке предусматривают кастом параметр который транслируется как есть насквозь от регистрации к самому его вызову.

    а у тебя в параметрах задекларированы только буфер и длина, которые у тебя и так есть

    вангую что прототип не такой
  • Tiger (17.10.17 00:03) [7]
    Вернула 0 - нет ошибок :(
  • Tiger (17.10.17 00:09) [8]
    Такое api. Вот и h-файла описание

    typedef void (* DECODE_NOTIFY_CALLBACK)(void *buf, DWORD DataLen);



    Вот куски из рабочего примера на C

    Привязка Callback

    void RecvDataFromSocketCallBack (void *Buf, DWORD len);

    .....

    EnableDecodeNotify(hConnect, NULL, ENABLE_DECODE_NOTIFY | USE_USER_DEFINE_RECORD_SUFFIX | DEFINE_RECORD_SUFFIX1(0x0d) | DEFINE_RECORD_SUFFIX2(0x0a), Buf_Notify ,sizeof(Buf_Notify), RecvDataFromSocketCallBack);

    .....

    void RecvDataFromSocketCallBack (void *Buf, DWORD len)
    {
    }



  • rrrrrr © (17.10.17 00:13) [9]
    тогда косяк с паскалевским аналогом буфера.

    я бы для начала просто сделал гетмем и пойнтер на него
  • Tiger (17.10.17 00:17) [10]
    Мне кажется не в параметрах дело. Я их пока не обрабатываю (хай в стеке висит что угодно) -  функция то должна отработать в любом случае - так как Callback должен передать управление на адрес процедуры.

    procedure MyDecodeNotify2(Buffer: PAnsiChar; Size:longword); stdcall;
    begin
       MessageBeep(MB_OK);
    end;
  • Tiger (17.10.17 00:23) [11]
    P.S. Не работает и с буфером...
  • Игорь Шевченко © (17.10.17 10:26) [12]

    > Есть пример на С и VB в котором Callback работает


    Секретные ? Если нет, то выложи, всегда проще смотреть, где ты накосячил при переводе на Delphi, чем гадать
  • Tiger (18.10.17 01:48) [13]
    Выше есть заголовки с примера на С.

    На VB код такой


       Dim hConnect As Integer
       Dim myCallBack As DelegateNotifyCallBack
       Dim UnmanagedPointerBuf As IntPtr = Marshal.AllocHGlobal(256)

    .......

               OP = &H1 Or &H20 Or 13 << 16 Or 10 << 24 'ENABLE_DECODE_NOTIFY | USE_USER_DEFINE_RECORD_SUFFIX | DEFINE_RECORD_SUFFIX1(13) | DEFINE_RECORD_SUFFIX2(10)
               myCallBack = New DelegateNotifyCallBack(AddressOf RecvDataFromSocketCallBack)
               ImportSDK.EnableDecodeNotify(hConnect, IntPtr.Zero, OP, UnmanagedPointerBuf, 256, myCallBack)

    ........

       Public Sub RecvDataFromSocketCallBack(ByVal ptr_Buf As IntPtr, ByVal len As Integer)

       End Sub





    Module ImportSDK

       <UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
       Public Delegate Sub DelegateNotifyCallBack(ByVal pbuf As IntPtr, ByVal len As Integer)

    ......

       <DllImport(DllName)> Function EnableDecodeNotify(ByVal hConnect As Int32, ByVal hWnd As IntPtr, ByVal OP As UInt32, ByVal info As IntPtr, ByVal BufferSize As Integer, ByVal callback As DelegateNotifyCallBack) As Int32
       End Function

  • Leonid Troyanovsky © (18.10.17 08:44) [14]

    > Tiger   (16.10.17 22:19) 

    >  'FSC.DLL' name '_EnableDecodeNotify';

    А чего вдруг палка снизу?

    > Вернула 0 - нет ошибок :(

    Неубедительно.

    --
    Regards, LVT.
  • rrrrrrr © (18.10.17 08:55) [15]
    myCallBack = New DelegateNotifyCallBack(AddressOf RecvDataFromSocketCallBack)
    ...
    Public Delegate Sub DelegateNotifyCallBack(ByVal pbuf As IntPtr, ByVal len As Integer)
    ...

    из примера если он рабочий ясно,
    что в D на роль этого колбэка не подойтет ordinal procedure/function

    так как в примере юзается делегат и в EnableDecodeNotify передается не адрес, а объект
 
Конференция "Начинающим" » Не работает Callback из DLL [D2005, XP]
Есть новые Нет новых   [118488   +59][b:0][p:0.003]