Has anyone adapted the ACE client engine function AdsRegisterCallbackFunction to an Xbase++ function.
I need to abort queries that may take a long time.
ADS Register Callback function
ADS Register Callback function
The eXpress train is coming - and it has more cars.
Re: ADS Register Callback function
Hi Roger
I asked Pablo and he said not complex using ot4xb_mini_rt_asm.ch
to delegate the call to a method of an xbase++ object
this is a sample from an unrelated project
// typedef int (STDCALL PMY_CALLBACK)(void lpObj, int event_id, int cparam, void *param[], int cbparam[]);
static function _get_dsink()
local pMethodName
local hXppRt1
local p__conNew
local p__conPutNL
local p__conCallMethodPa
local p__conGetNL
local p__conRelease
local _asm_
local n,p
if pf__callback != NIL
return pf__callback
end
pMethodName := _xgrab("_dsink_")
hXppRt1 := @kernel32:GetModuleHandleA("xpprt1.dll")
p__conNew := nGetProcAddress(hXppRt1,"__conNew")
p__conPutNL := nGetProcAddress(hXppRt1,"__conPutNL")
p__conCallMethodPa := nGetProcAddress(hXppRt1,"__conCallMethodPa")
p__conGetNL := nGetProcAddress(hXppRt1,"__conGetNL")
p__conRelease := nGetProcAddress(hXppRt1,"__conRelease")
_asm_ := ""
_asm _stdcall_prolog_(7) // dsink( 1 con , 2 id , 3 cp , 4 pp , 5 cbp ) -> result
__asm mov dword var 7 , val 0 // int result = 0;
_asm mov eax , arg 1 // ContainerHandle Self = conNew( con );
__asm push eax
_asm _call__cdecl( p__conNew , 1 )
__asm mov var 6 , eax
for n := 1 to 4
_asm mov eax , arg (n+1) // ContainerHandle p<n> = conPutNL(0,<argn+1>);
__asm push eax
__asm push byte 0
_asm _call__cdecl( p__conPutNL , 2 )
__asm mov var (6-n) , eax
next
_asm push byte 0 // ContainerHandle conr = conPutNL(0,0);
__asm push byte 0
_asm _call__cdecl( p__conPutNL , 2 )
__asm mov var 1 , eax
_asm lea eax , var 6 // conCallMethodPa(conr,pMethodName,5,&Self);
__asm push eax
__asm push byte 5
__asm push dword pMethodName
__asm mov eax , var 1
__asm push eax
_asm _call__cdecl( p__conCallMethodPa , 4 )
_asm lea eax , var 7 // conGetNL(conr,&result);
__asm push eax
__asm mov eax , var 1
__asm push eax
_asm _call__cdecl( p__conGetNL , 2 )
for n := 1 to 6
_asm mov eax , var n // conRelease(p<n>);
__asm push eax
_asm _call__cdecl( p__conRelease , 1 )
next
__asm mov eax , var 7 // return result;
_asm _stdcall_epilog_( 5 )
n := Len(__asm__)
p := _xgrab( nOr(n,15) + 1 + 16)
pf__callback := p + 16
PokeStr(pf__callback,,__asm__)
PokeDWord(p,0,n)
PokeDWord(p,4,pMethodName)
@kernel32:VirtualProtect(pf__callback,n,64,p + 8)
OT4XB_PUSH_EXIT_CB( {|| _destroy_dsink() } )
return pf__callback // this is a static var
and the destructor
static function _destroy_dsink()
local p,mn,cb,dw
if pf__callback != NIL
p := (pf_callback - 16)
pf_callback := NIL
cb := PeekDWord(p,0)
mn := PeekDWord(p,4)
dw := PeekDWord(p,8)
@kernel32:VirtualProtect(p+16,cb,dw,p + 12)
_xfree(p)
_xfree(mn)
end
return NIL
of course you will need to adapt to the required prototype parameters and return types
in this project the callback has a parameter void lpObj so we providing _var2con(Self)
as here we don't have a cargo parameter for user data we need to embed _var2con(Self)
inside the callback and remember to _conRelease( conSelf ) when destroying the callback
( 1 per instance object )
I'm in a middle of a project making some inhouse tools with ADS so probably
soon or later will need to make a generic one for myself
ping me in 2 - 3 weeks to refresh my memory because even I would like to use those
callbacks not a priority
I can remove the project specific or sensitive info and let you share with roger
Best Regard
Hector
I asked Pablo and he said not complex using ot4xb_mini_rt_asm.ch
to delegate the call to a method of an xbase++ object
this is a sample from an unrelated project
// typedef int (STDCALL PMY_CALLBACK)(void lpObj, int event_id, int cparam, void *param[], int cbparam[]);
static function _get_dsink()
local pMethodName
local hXppRt1
local p__conNew
local p__conPutNL
local p__conCallMethodPa
local p__conGetNL
local p__conRelease
local _asm_
local n,p
if pf__callback != NIL
return pf__callback
end
pMethodName := _xgrab("_dsink_")
hXppRt1 := @kernel32:GetModuleHandleA("xpprt1.dll")
p__conNew := nGetProcAddress(hXppRt1,"__conNew")
p__conPutNL := nGetProcAddress(hXppRt1,"__conPutNL")
p__conCallMethodPa := nGetProcAddress(hXppRt1,"__conCallMethodPa")
p__conGetNL := nGetProcAddress(hXppRt1,"__conGetNL")
p__conRelease := nGetProcAddress(hXppRt1,"__conRelease")
_asm_ := ""
_asm _stdcall_prolog_(7) // dsink( 1 con , 2 id , 3 cp , 4 pp , 5 cbp ) -> result
__asm mov dword var 7 , val 0 // int result = 0;
_asm mov eax , arg 1 // ContainerHandle Self = conNew( con );
__asm push eax
_asm _call__cdecl( p__conNew , 1 )
__asm mov var 6 , eax
for n := 1 to 4
_asm mov eax , arg (n+1) // ContainerHandle p<n> = conPutNL(0,<argn+1>);
__asm push eax
__asm push byte 0
_asm _call__cdecl( p__conPutNL , 2 )
__asm mov var (6-n) , eax
next
_asm push byte 0 // ContainerHandle conr = conPutNL(0,0);
__asm push byte 0
_asm _call__cdecl( p__conPutNL , 2 )
__asm mov var 1 , eax
_asm lea eax , var 6 // conCallMethodPa(conr,pMethodName,5,&Self);
__asm push eax
__asm push byte 5
__asm push dword pMethodName
__asm mov eax , var 1
__asm push eax
_asm _call__cdecl( p__conCallMethodPa , 4 )
_asm lea eax , var 7 // conGetNL(conr,&result);
__asm push eax
__asm mov eax , var 1
__asm push eax
_asm _call__cdecl( p__conGetNL , 2 )
for n := 1 to 6
_asm mov eax , var n // conRelease(p<n>);
__asm push eax
_asm _call__cdecl( p__conRelease , 1 )
next
__asm mov eax , var 7 // return result;
_asm _stdcall_epilog_( 5 )
n := Len(__asm__)
p := _xgrab( nOr(n,15) + 1 + 16)
pf__callback := p + 16
PokeStr(pf__callback,,__asm__)
PokeDWord(p,0,n)
PokeDWord(p,4,pMethodName)
@kernel32:VirtualProtect(pf__callback,n,64,p + 8)
OT4XB_PUSH_EXIT_CB( {|| _destroy_dsink() } )
return pf__callback // this is a static var
and the destructor
static function _destroy_dsink()
local p,mn,cb,dw
if pf__callback != NIL
p := (pf_callback - 16)
pf_callback := NIL
cb := PeekDWord(p,0)
mn := PeekDWord(p,4)
dw := PeekDWord(p,8)
@kernel32:VirtualProtect(p+16,cb,dw,p + 12)
_xfree(p)
_xfree(mn)
end
return NIL
of course you will need to adapt to the required prototype parameters and return types
in this project the callback has a parameter void lpObj so we providing _var2con(Self)
as here we don't have a cargo parameter for user data we need to embed _var2con(Self)
inside the callback and remember to _conRelease( conSelf ) when destroying the callback
( 1 per instance object )
I'm in a middle of a project making some inhouse tools with ADS so probably
soon or later will need to make a generic one for myself
ping me in 2 - 3 weeks to refresh my memory because even I would like to use those
callbacks not a priority
I can remove the project specific or sensitive info and let you share with roger
Best Regard
Hector
Re: ADS Register Callback function
If this is the simple (not complex) method, then I would hate to see the complex method.I asked Pablo and he said not complex using ot4xb_mini_rt_asm.ch
to delegate the call to a method of an xbase++ object
Thank you.
The eXpress train is coming - and it has more cars.
Re: ADS Register Callback function
Just what I thought.If this is the simple (not complex) method, then I would hate to see the complex method.
