Hi,
I use approach listed below. And I suggest... not to use it! :)
And this code is NOT the one I want to see in Harbour. It's Windows
32bit only, code is on data segment, etc.
Syntax:
CallProc( ptrFunc, param1, param2, ... )
or
cStackFrame := L2BIN(something) + L2BIN(something) + ...
CallProcByFrame( ptrFunc | "cDll:cFunc", cStackFrame )
Actually when I've wrote "I use approach listed below", I was wrong. My
friends were using it in cases they need some WinAPI call. In a few days
I include function wrapper to call this WinAPI in my CAWI library, and
they delete this CallProc hack. That was time of developing CAWI. We
have not used CallProc() for a few years now.
Have a good GPF pleasure,
Mindaugas
Viktor Szakáts wrote:
I don't have huge recruiting experiences, so cannot tell, but maybe
someone in our crew (Mindaugas :) could find it interesting in the
future and even find time for it.
Of course everyone is welcome and you can try getting ppl interested,
I seem to recall there is some infrastructure for that on sf.net even.
Brgds,
Viktor
static const BYTE CallProcByStackFrameCode[] = {
0x55, // push ebp
0x8B, 0xEC, // mov ebp,esp
0x8B, 0x4D, 0x10, // mov ecx,dword ptr [ebp+16]
0x67, 0xE3, 0x10, // jcxz @@noparam
0x8B, 0x5D, 0x0C, // mov ebx,dword ptr [ebp+12]
0x2B, 0xE1, // sub esp,ecx
0x8B, 0xD4, // mov edx,esp
0x8A, 0x03, // @@loop: mov al,byte ptr [ebx]
0x36, 0x88, 0x02, // mov byte ptr ss:[edx],al
0x43, // inc ebx
0x42, // inc edx
0xE2, 0xF7, // loop @@loop
0x8B, 0x45, 0x08, // @@noparam: mov eax,dword ptr [ebp+8]
0xFF, 0xD0, // call eax
0x8B, 0xE5, // mov esp,ebp
0x5D, // pop ebp
0xC3}; // ret
typedef int (* CallProcByStackFrameFunc) (void*, void*, int);
CallProcByStackFrameFunc CallProcByStackFrame =
(CallProcByStackFrameFunc)CallProcByStackFrameCode;
HB_FUNC ( CALLPROCBYSTACKFRAME )
{
if ( ISCHAR( 2 ) )
hb_retnl( CallProcByStackFrame( hb_parptr( 1 ), hb_parc( 2 ),
hb_parclen( 2 ) ) );
else
hb_retnl( CallProcByStackFrame( hb_parptr( 1 ), NULL, 0 ) );
}
HB_FUNC ( CALLPROC )
{
// TODO: this function always returns LONG type. It could be pointer!
long pbuf[ 10 ];
int i, j, pcount, storn = 0, storc = 0, storp = 0;
char *pstr, *pFuncName;
HINSTANCE hInst;
void* pFunc;
pcount = hb_parinfo( 0 );
j = 9;
for ( i = 2; i <= pcount; i++ )
{
if ( i - 2 >= j )
{
// ### runerror
hb_ret();
return;
}
if ( ISNUM( i ) )
{
if ( ISBYREF( i ) )
{
pbuf[ j ] = (long) hb_parnl( i );
pbuf[ i - 2 ] = (long) &pbuf[ j ];
j--;
storn |= 1 << ( i - 2 );
}
else
pbuf[ i - 2 ] = (long) hb_parnl( i );
}
else if ( ISCHAR( i ) )
{
if ( ISBYREF( i ) )
{
pbuf[ i - 2 ] = (long) hb_xgrabcopy( hb_parclen( i ) + 1,
hb_parc( i ) );
storc |= 1 << ( i - 2 );
}
else
pbuf[ i - 2 ] = (long) hb_parc( i );
}
else if ( ISPOINTER( i ) )
{
if ( ISBYREF( i ) )
{
pbuf[ j ] = (long) hb_parptr( i );
pbuf[ i - 2 ] = (long) &pbuf[ j ];
j--;
storp |= 1 << ( i - 2 );
}
else
pbuf[ i - 2 ] = (long) hb_parptr( i );
}
else if ( ISLOG(i) )
pbuf[ i-2 ] = (long) hb_parl( i );
}
hInst = NULL;
if ( ISPOINTER( 1 ) ) pFunc = hb_parptr( 1 );
else
{
pstr = hb_parc(1);
if ( ( pFuncName = strrchr( pstr, ':' ) ) == NULL )
{
// ### runerror
hb_ret();
return;
}
*pFuncName = '\0';
hInst = LoadLibrary( pstr );
*pFuncName = ':';
pFunc = GetProcAddress( hInst, pFuncName + 1 );
}
if ( ! pFunc )
{
// ### runerror
hb_ret();
return;
}
hb_retnl( CallProcByStackFrame( pFunc, &pbuf, ( pcount - 1 ) * 4 ) );
if ( hInst )
FreeLibrary( hInst );
for ( i = 0; i < pcount - 1; i++ )
{
if ( storn & (1 << i) )
{
hb_stornl( * (long*) pbuf[ i ], i + 2 );
}
else if ( storc & (1 << i) )
{
hb_storclen( (char*) pbuf[ i ], hb_parclen( i + 2 ), i + 2 );
hb_xfree( (char*) pbuf[ i ] );
}
else if ( storp & (1 << i) )
{
hb_storptr( (void*) pbuf[ i ], i + 2 );
}
}
}
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour