-
Использую чужую 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 не вызывается
-
Подозреваю такие варианты:
1. Неправильно перевел синтаксис процедуры из С 2. Неправильно передаю адрес процедуры Callback 3. Нельзя использовать Callback-процедуру в объекте 4. Для вызова Callback нужны дополнительные действия.
Есть пример на С и VB в котором Callback работает
-
Функции обратного вызова нельзя объявлять как члены класса, ибо в них неявно передаётся указатель на объект. Надо объявлять только так:
TDecodeNotify = procedure (Buffer: PAnsiChar; Size: DWORD);
procedure DecodeNotify(Buffer: PAnsiChar; Size: DWORD); begin .... end;
DebugInt:=FSC_EnableDecodeNotify(hConnect, 0, Option, @Buffer, SizeOf(Buffer), DecodeNotify);
-
1. Не помогло - callback так и не отрабатывается :(
2. Как можно обойти ограничение? В объекте есть данные которые нужны для дальнейшей обработки события.
-
int EnableDecodeNotify(......
смотри что она тебе вернула и кури коды ошибок в доке к длл
-
Как можно обойти ограничение?
Option: longword
сам колбек делаем отдельно-стоящим, а через option передаем ссылку на объект когда исправишь ошибки, объект к тебе прилетит в вызов колбэка.
-
плюс не видно оригинального прототипа для DECODE_NOTIFY_CALLBACK
я не думаю что он вот такой вот procedure MyDecodeNotify(Buffer: PAnsiChar; Size:longword); stdcall;
в православном правильном колбэке предусматривают кастом параметр который транслируется как есть насквозь от регистрации к самому его вызову.
а у тебя в параметрах задекларированы только буфер и длина, которые у тебя и так есть
вангую что прототип не такой
-
Вернула 0 - нет ошибок :(
-
Такое 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)
-
тогда косяк с паскалевским аналогом буфера.
я бы для начала просто сделал гетмем и пойнтер на него
-
Мне кажется не в параметрах дело. Я их пока не обрабатываю (хай в стеке висит что угодно) - функция то должна отработать в любом случае - так как Callback должен передать управление на адрес процедуры.
procedure MyDecodeNotify2(Buffer: PAnsiChar; Size:longword); stdcall; begin MessageBeep(MB_OK); end;
-
P.S. Не работает и с буфером...
-
> Есть пример на С и VB в котором Callback работает
Секретные ? Если нет, то выложи, всегда проще смотреть, где ты накосячил при переводе на Delphi, чем гадать
-
Выше есть заголовки с примера на С. На 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
-
> Tiger (16.10.17 22:19)
> 'FSC.DLL' name '_EnableDecodeNotify';
А чего вдруг палка снизу?
> Вернула 0 - нет ошибок :(
Неубедительно.
-- Regards, LVT.
-
myCallBack = New DelegateNotifyCallBack(AddressOf RecvDataFromSocketCallBack) ... Public Delegate Sub DelegateNotifyCallBack(ByVal pbuf As IntPtr, ByVal len As Integer) ...
из примера если он рабочий ясно, что в D на роль этого колбэка не подойтет ordinal procedure/function
так как в примере юзается делегат и в EnableDecodeNotify передается не адрес, а объект
|