Author Topic: SBT  (Read 35433 times)

0 Members and 1 Guest are viewing this topic.

JRS

  • Guest
Re: SBT
« Reply #15 on: September 21, 2014, 01:18:25 AM »
Quote
But then it's only easy to overlook some minute detail in such a complex mechanism as a variant-based interpreter.

SB is forgiving for the most part but when it decides to fight with you, it can get bloody.

JRS

  • Guest
Re: SBT
« Reply #16 on: September 26, 2014, 10:48:51 PM »
Charles,

If you have time I could use your guidance with our famous scriba_CallArgEx embedded indirect script calling function, The MyICall example in the trial extension model works but it's an extension API call not an embedded API call which I'm trying to do. I took a peek at your DLLC code but your calling the function by address and not a scriba.h  scriba_CallArgEx C call. Here is were I'm at with the SB_Sub function in the SBT extension module. Can you show me how I can substitute besHOOK_CALLSCRIBAFUNCTION with the embedding scriba_CallArgEx call?

Code: [Select]
besFUNCTION(SB_Address)
  DIM AS int sbobj, funcsernum;
  DIM AS char PTR funcname;
  besARGUMENTS("iz")
    AT sbobj, AT funcname
  besARGEND
  funcsernum = scriba_LookupFunctionByName(sbobj, funcname);
  besRETURN_LONG(funcsernum);
besEND

besFUNCTION(SB_Sub)
  DIM AS VARIABLE Argument;
  DIM AS VARIABLE pArgument;
  DIM AS VARIABLE FunctionResult;
  DIM AS unsigned long ulEntryPoint;
  DIM AS unsigned long i;
  DIM AS int sbobj;
  Argument = besARGUMENT(1);
  besDEREFERENCE(Argument);
  sbobj = LONGVALUE(Argument);
  Argument = besARGUMENT(2);
  besDEREFERENCE(Argument);
  ulEntryPoint = LONGVALUE(Argument);
  pArgument = besNEWARRAY(0,besARGNR-3);
  for( i=3 ; i <= (unsigned)besARGNR ; i++ ){
     pArgument->Value.aValue[i-3] = besARGUMENT(i);
     }
  besHOOK_CALLSCRIBAFUNCTION(ulEntryPoint, pArgument->Value.aValue,  besARGNR-2, &FunctionResult);
  for( i=3 ; i <= (unsigned)besARGNR ; i++ ){
     pArgument->Value.aValue[i-3] = NULL;
     }
  besRELEASE(pArgument);
  besRELEASE(FunctionResult);
besEND

Here is Dave's C code used in his COM extension module that does what I want but it hard to see through the COM wrapper.

Code: [Select]
VARIANT __stdcall SBCallBackEx(int EntryPoint, VARIANT *pVal)
{
#pragma EXPORT

  pSupportTable pSt = g_pSt;
  VARIABLE FunctionResult;
  _variant_t vRet;

  if(pSt==NULL){
  MessageBox(0,"pSupportTable is not set?","",0);
  return vRet.Detach();
  }
 
    USES_CONVERSION;
char buf[1024]={0};
    HRESULT hr;
long lResult;
long lb;
long ub;
    SAFEARRAY *pSA = NULL;

//we only accept variant arrays..
if (V_VT(pVal) == (VT_ARRAY | VT_VARIANT | VT_BYREF)) //24588
pSA = *(pVal->pparray);
//else if (V_ISARRAY(pVal) && V_ISBYREF(pVal)) //array of longs here
didnt work out maybe latter
// pSA = *(pVal->pparray);
else
{
if (V_VT(pVal) == (VT_ARRAY | VT_VARIANT))
pSA = pVal->parray;
else
return vRet.Detach();//"Type Mismatch [in] Parameter."
};

    long dim = SafeArrayGetDim(pSA);
if(dim != 1) return vRet.Detach();

lResult = SafeArrayGetLBound(pSA,1,&lb);
lResult = SafeArrayGetUBound(pSA,1,&ub);

lResult=SafeArrayLock(pSA);
    if(lResult) return vRet.Detach();

    _variant_t vOut;
_bstr_t cs;

int sz = ub-lb+1;
    VARIABLE pArg = besNEWARRAY(0,sz);

//here we proxy the array of COM types into the array of script basic
types element by element.
// note this we only support longs and strings. floats will be rounded,
objects converted to objptr()
//  bytes and integers are ok too..basically just not float and
currency..which SB doesnt support anyway..
    for (long l=lb; l<=ub; l++) {
if( SafeArrayGetElement(pSA, &l, &vOut) == S_OK ){
if(vOut.vt == VT_BSTR){
char* cstr = __B2C(vOut.bstrVal);
int slen = strlen(cstr);
pArg->Value.aValue[l] = besNEWMORTALSTRING(slen);
memcpy(STRINGVALUE(pArg->Value.aValue[l]),cstr,slen);
free(cstr);
}
else{
if(vOut.vt == VT_DISPATCH){
//todo register handle? but how do we know the lifetime of it..
//might only be valid until this exits, or forever?
}
pArg->Value.aValue[l] = besNEWMORTALLONG;
LONGVALUE(pArg->Value.aValue[l]) = vOut.lVal;
}
}
    }

  lResult=SafeArrayUnlock(pSA);
  if (lResult) return vRet.Detach();
 
  besHOOK_CALLSCRIBAFUNCTION(EntryPoint,
pArg->Value.aValue,
                             sz,
                             &FunctionResult);

  for (long l=0; l <= sz; l++) {
besRELEASE(pArg->Value.aValue[l]);
     pArg->Value.aValue[l] = NULL;
  }

  if(FunctionResult->vType == VTYPE_STRING){
char* myStr = GetCString(FunctionResult);
vRet.SetString(myStr);
free(myStr);
  }
  else{
  switch( TYPE(FunctionResult) )
  {   
case VTYPE_DOUBLE:
case VTYPE_ARRAY:
case VTYPE_REF:
MessageBoxA(0,"Arguments of script basic types [double, ref, array] not
supported","Error",0);
break;
default:
vRet = LONGVALUE(FunctionResult);
  }
  }

  besRELEASE(pArg);
  besRELEASE(FunctionResult);

  return vRet.Detach();
}

Charles Pegge

  • Guest
Re: SBT
« Reply #17 on: September 27, 2014, 02:49:24 PM »

Hi John,

SB pointy-pointys are so confusing.

I'm trying to familiarise myself with hook functions, but appear to be getting a null pointer to them, in the ExecuteObject (pEo).

This other way of calling requires pProgram:

pst->scriba_CallArgEx)(pSbProgram pProgram, unsigned long lEntryNode, pSbData ReturnValue, unsigned long cArgs, pSbData Args);






JRS

  • Guest
Re: SBT
« Reply #18 on: September 27, 2014, 03:07:34 PM »
Quote
This other way of calling requires pProgram:

I pass the pProgram pointer to every SBT function I call after SB_New().

pst->scriba_CallArgEx)(pSbProgram pProgram, unsigned long lEntryNode, pSbData ReturnValue, unsigned long cArgs, pSbData Args);

Is this a typo above?  I'm assuming that the above is a prototype definition of the function and not what I would use to call it.

Thanks for helping me get embedded SB script function calling working. As Peter said in the docs, this is the most complex function in the API.


JRS

  • Guest
SBT
« Reply #19 on: September 27, 2014, 05:11:20 PM »
Charles,

This hacked example works. The missing piece is creating the argData structure and not having to use scriba_NewSbArgs. This uses the pProgram I'm passing and the the function serial number from SB_Address() of SUB test in the embedded instance.

Code: Text
  1. besFUNCTION(SB_Address)
  2.   DIM AS int sbobj, funcsernum;
  3.   DIM AS char PTR funcname;
  4.   besARGUMENTS("iz")
  5.     AT sbobj, AT funcname
  6.   besARGEND
  7.   funcsernum = scriba_LookupFunctionByName(sbobj, funcname);
  8.   besRETURN_LONG(funcsernum);
  9. besEND
  10.  
  11. besFUNCTION(SB_Sub)
  12.   DIM AS VARIABLE Argument;
  13. //DIM AS VARIABLE pArgument;
  14. //DIM AS VARIABLE FunctionResult;
  15.   DIM AS SbData ReturnData;
  16.   DIM AS pSbData ArgData;
  17.   DIM AS unsigned long ulEntryPoint;
  18.   DIM AS unsigned long i;
  19.   DIM AS int sbobj, ok;
  20.   Argument = besARGUMENT(1);
  21.   besDEREFERENCE(Argument);
  22.   sbobj = LONGVALUE(Argument);
  23.   Argument = besARGUMENT(2);
  24.   besDEREFERENCE(Argument);
  25.   ulEntryPoint = LONGVALUE(Argument);
  26. //pArgument = besNEWARRAY(0,besARGNR-3);
  27. //for( i=3 ; i <= (unsigned)besARGNR ; i++ ){
  28. //   pArgument->Value.aValue[i-3] = besARGUMENT(i);
  29. //   }
  30. //besHOOK_CALLSCRIBAFUNCTION(ulEntryPoint, pArgument->Value.aValue,  besARGNR-2, &FunctionResult);
  31.   ArgData = scriba_NewSbArgs(sbobj, "i r s", 10, .20, "Thirty");
  32.   ok = scriba_CallArgEx(sbobj, ulEntryPoint, &ReturnData, 3, ArgData);  
  33.  
  34. //for( i=3 ; i <= (unsigned)besARGNR ; i++ ){
  35. //   pArgument->Value.aValue[i-3] = NULL;
  36. //   }
  37. //besRELEASE(pArgument);
  38. //besRELEASE(FunctionResult);
  39. scriba_DestroySbArgs(sbobj, ArgData, 3);
  40. besEND
  41.  

Code: Text
  1. DECLARE SUB SB_New ALIAS "SB_New" LIB "sbt"
  2. DECLARE SUB SB_Configure ALIAS "SB_Configure" LIB "sbt"
  3. DECLARE SUB SB_Load ALIAS "SB_Load" LIB "sbt"
  4. DECLARE SUB SB_Run ALIAS "SB_Run" LIB "sbt"
  5. DECLARE SUB SB_NoRun ALIAS "SB_NoRun" LIB "sbt"
  6. DECLARE SUB SB_Address ALIAS "SB_Address" LIB "sbt"
  7. DECLARE SUB SB_Sub ALIAS "SB_Sub" LIB "sbt"
  8. DECLARE SUB SB_Destroy ALIAS "SB_Destroy" LIB "sbt"
  9.  
  10. sb = SB_New()
  11. ok = SB_Configure(sb, "/etc/scriba/basic.conf")
  12. ok = SB_Load(sb, "test3.sb")
  13. ok = SB_NoRun(sb)
  14. faddr = SB_Address(sb, "main::test")
  15. SB_Sub(sb, faddr)
  16. SB_Destroy(sb)
  17.  

Code: Text
  1. ' Test3 - Host indirect call
  2.  
  3. SUB test(arg1,arg2,arg3)
  4.   PRINT arg1,"\n"
  5.   PRINT FORMAT("%g",arg2),"\n"
  6.   PRINT arg3,"\n"
  7. END SUB
  8.  

Output

jrs@laptop:~/sb/sb22/sbt$ scriba embed.sb
10
0.2
Thirty
jrs@laptop:~/sb/sb22/sbt$

JRS

  • Guest
Re: SBT
« Reply #20 on: September 27, 2014, 07:49:50 PM »
Charles,

This is where all the action is.

Code: Text
  1. =H scriba_NewSbArgs()
  2.  
  3. Whenever you want to handle the variable values that are returned by the scriba subroutine
  4. you have to call R<scriba_CallArgEx()>. This function needs the arguments passed in an array of T<SbDtata> type.
  5.  
  6. This function is a usefuly tool to convert C variables to an array of T<SbData>
  7.  
  8. /*FUNCTION*/
  9. SCRIBA_MAIN_LIBSPEC pSbData scriba_NewSbArgs(pSbProgram pProgram,
  10.                          char *pszFormat, ...
  11.   ){
  12. /*noverbatim
  13. The arguments passed are
  14.  
  15. =itemize
  16. =item T<pProgram> is the class variable
  17. =item T<pszFormat> is the format string
  18. =noitemize
  19.  
  20. The format string is case insensitive. The characters T<u>, T<i>, T<r>, T<b> and T<s> have meaning.
  21. All other characters are ignored. The format characters define the type of the arguments
  22. from left to right.
  23.  
  24. =itemize
  25. =item T<u> means to pass an T<undef> to the SUB. This format character is exceptional that it does not
  26. consume any function argument.
  27. =item T<i> means that the next argument has to be T<long> and it is passed to the BASIC SUB as an integer.
  28. =item T<r> means that the next argument has to be T<double> and it is passed to the BASIC SUB as a real.
  29. =item T<s> means that the next argument has to be T<char *> and it is passed to the BASIC SUB as a string.
  30. =item T<b> means that the next two arguments has to be T<long cbBuffer> and T<unsigned char *Buffer>.
  31. The T<cbBuffer> defines the leng of the T<Buffer>.
  32. =noitemize
  33.  
  34. Example:
  35.  
  36. =verbatim
  37.  
  38. pSbData MyArgs;
  39.  
  40.  
  41.   MyArgs = scriba_NewSbArgs(pProgram,"i i r s b",13,14,3.14,"string",2,"two character string");
  42.   if( MyArgs == NULL )error("memory alloc");
  43.  
  44.   scriba_CallArgEx(pProgram,lEntry,NULL,5,MyArgs);
  45.  
  46. =noverbatim
  47.  
  48. This example passes five arguments to the ScriptBasic subroutine. Note that the last one is only
  49. two character string, the rest of the characters are ignored.
  50.  
  51. CUT*/
  52.   va_list marker;
  53.   unsigned long cArgs,i;
  54.   char *s;
  55.   char *arg;
  56.   pSbData p;
  57.  
  58.   if( pszFormat == NULL )return NULL;
  59.  
  60.   cArgs = 0;
  61.   s = pszFormat;
  62.   while( *s ){
  63.     switch( *s++ ){
  64.       case 'U': /* undef argument */
  65.       case 'u': /* It eats no actual C level caller argument */
  66.  
  67.       case 'B': /* byte argument   */
  68.       case 'b': /* it eats two arguments: a length and the pointer to the byte stream */
  69.  
  70.       case 'S': /* string argument */
  71.       case 's':
  72.       case 'I': /* Integer argument */
  73.       case 'i':
  74.       case 'R': /* Real number argument */
  75.       case 'r':
  76.         cArgs ++;
  77.         break;
  78.       default:; /* ignore all non-format characters */
  79.       }
  80.     }
  81.   p = alloc_Alloc(sizeof(SbData)*cArgs,pProgram->pMEM);
  82.   if( p == NULL )return NULL;  
  83.  
  84.   i = 0;
  85.   va_start(marker,pszFormat);
  86.   s = pszFormat;
  87.   while( *s ){
  88.     switch( *s++ ){
  89.       case 'U':
  90.       case 'u':
  91.         p[i].type = SBT_UNDEF;
  92.         i++;
  93.         break;
  94.       case 'B': /* byte stream argument */
  95.       case 'b':
  96.         p[i].type = SBT_STRING;
  97.         p[i].size = va_arg(marker, long);
  98.         arg = va_arg(marker, char *);
  99.         if( arg == NULL && p[i].size != 0 ){
  100.           p[i++].type = SBT_UNDEF;
  101.           break;
  102.           }
  103.         p[i].size =  strlen(arg);
  104.         if( p[i].size ){
  105.           p[i].v.s = alloc_Alloc(p[i].size,pProgram->pMEM);
  106.           if( p[i].v.s == NULL ){
  107.             while( i ){
  108.               if( p[i].type == SBT_STRING && p[i].v.s )alloc_Free(p[i].v.s,pProgram->pMEM);
  109.               i--;
  110.               }
  111.             alloc_Free(p,pProgram->pMEM);
  112.             return NULL;
  113.             }
  114.           memcpy(p[i].v.s,arg,p[i].size);
  115.           }else{
  116.           p[i].v.s = NULL;
  117.           }
  118.         i++;
  119.         break;
  120.       case 'S': /* string argument */
  121.       case 's':
  122.         p[i].type = SBT_STRING;
  123.         arg = va_arg(marker, char *);
  124.         if( arg == NULL )arg = "";
  125.         p[i].size = strlen(arg);
  126.         if( p[i].size ){
  127.           p[i].v.s = alloc_Alloc(p[i].size,pProgram->pMEM);
  128.           if( p[i].v.s == NULL ){
  129.             while( i ){
  130.               if( p[i].type == SBT_STRING && p[i].v.s )alloc_Free(p[i].v.s,pProgram->pMEM);
  131.               i--;
  132.               }
  133.             alloc_Free(p,pProgram->pMEM);
  134.             return NULL;
  135.             }
  136.           memcpy(p[i].v.s,arg,p[i].size);
  137.           }else{
  138.           p[i].v.s = NULL;
  139.           }
  140.         i++;
  141.         break;
  142.       case 'I': /* Integer argument */
  143.       case 'i':
  144.         p[i].type = SBT_LONG;
  145.         p[i].v.l = va_arg(marker, long);
  146.         i++;
  147.         break;
  148.       case 'R': /* Real number argument */
  149.       case 'r':
  150.         p[i].type = SBT_DOUBLE;
  151.         p[i].v.d = va_arg(marker, double);
  152.         i++;
  153.         break;
  154.       }
  155.     }
  156.  
  157.   return p;
  158.   }
  159.  
  160. /*POD
  161. =H scriba_CallArgEx()
  162.  
  163. This is the most sophisticated function of the ones that call a ScriptBasic subroutine.
  164. This function is capable handling parameters to scriba subroutines, and returning the
  165. modified argument variables and the return value.
  166.  
  167. /*FUNCTION*/
  168. SCRIBA_MAIN_LIBSPEC int scriba_CallArgEx(pSbProgram pProgram,
  169.                      unsigned long lEntryNode,
  170.                      pSbData ReturnValue,
  171.                      unsigned long cArgs,
  172.                      pSbData Args
  173.   ){
  174. /*noverbatim
  175. The arguments:
  176. =itemize
  177. =item T<pProgram> is the program object pointer.
  178. =item T<lEntryNode> is the entry node index where the BASIC subroutine or function starts
  179.       (See R<scriba_Call()> note on how to get the entry node value.)
  180. =item T<ReturnValue> is the return value of the function or subroutine
  181. =item T<cArgs> is the number of argments passed to the function
  182. =item T<Args> argument data array
  183. =noitemize
  184. CUT*/
  185.   int iError;
  186.   VARIABLE vArgs;
  187.   VARIABLE vReturn;
  188.   unsigned long i;
  189.  
  190.   if( cArgs )
  191.     vArgs = memory_NewArray(pProgram->pEXE->pMo,0,cArgs-1);
  192.   else
  193.     vArgs = NULL;
  194.  
  195.   if( vArgs ){
  196.     for( i = 0 ; i < cArgs ; i ++ ){
  197.       switch( Args[i].type ){
  198.         case SBT_UNDEF:
  199.           vArgs->Value.aValue[i] = NULL;
  200.           break;
  201.         case SBT_STRING:
  202.           vArgs->Value.aValue[i] = memory_NewString(pProgram->pEXE->pMo,Args[i].size);
  203.           memcpy(STRINGVALUE(vArgs->Value.aValue[i]),Args[i].v.s,Args[i].size);
  204.           alloc_Free(Args[i].v.s,pProgram->pMEM);
  205.           break;
  206.         case SBT_LONG: /* Integer argument */
  207.           vArgs->Value.aValue[i] = memory_NewLong(pProgram->pEXE->pMo);
  208.           LONGVALUE(vArgs->Value.aValue[i]) = Args[i].v.l;
  209.           break;
  210.         case SBT_DOUBLE: /* Real number argument */
  211.           vArgs->Value.aValue[i] = memory_NewDouble(pProgram->pEXE->pMo);
  212.           DOUBLEVALUE(vArgs->Value.aValue[i]) = Args[i].v.d;
  213.           break;
  214.         }
  215.       }
  216.     }
  217.  
  218.   execute_ExecuteFunction(pProgram->pEXE,lEntryNode,cArgs,vArgs ? vArgs->Value.aValue : NULL ,&vReturn,&iError);
  219.   scriba_UndefSbData(pProgram,ReturnValue);
  220.  
  221.   if( ! iError && vReturn ){
  222.     switch( vReturn->vType ){
  223.       case VTYPE_LONG:
  224.         ReturnValue->type = SBT_LONG;
  225.         ReturnValue->v.l = LONGVALUE(vReturn);
  226.         break;
  227.       case VTYPE_DOUBLE:
  228.         ReturnValue->type = SBT_DOUBLE;
  229.         ReturnValue->v.d = DOUBLEVALUE(vReturn);
  230.         break;
  231.       case VTYPE_STRING:
  232.         ReturnValue->type = SBT_STRING;
  233.         /* we allocate a one byte longer buffer and append a terminating zero */
  234.         ReturnValue->size=STRLEN(vReturn);/* size is w/o the terminating zero */
  235.         ReturnValue->v.s = alloc_Alloc(ReturnValue->size+1,pProgram->pMEM);
  236.         if( ReturnValue->v.s ){
  237.           memcpy(ReturnValue->v.s,STRINGVALUE(vReturn),ReturnValue->size);
  238.           ReturnValue->v.s[ReturnValue->size] = (char)0;
  239.           }
  240.         break;
  241.       default:
  242.         ReturnValue->type = SBT_UNDEF;
  243.         break;
  244.       }
  245.     }
  246.  
  247.   if( vArgs && ! iError ){
  248.     for( i = 0 ; i < cArgs ; i ++ ){
  249.       if( vArgs->Value.aValue[i] == NULL ){
  250.         Args[i].type = SBT_UNDEF;
  251.         continue;
  252.         }
  253.       switch( vArgs->Value.aValue[i]->vType ){
  254.         case VTYPE_LONG:
  255.           Args[i].type = SBT_LONG;
  256.           Args[i].v.l = LONGVALUE(vArgs->Value.aValue[i]);
  257.           break;
  258.         case VTYPE_DOUBLE:
  259.           Args[i].type = SBT_DOUBLE;
  260.           Args[i].v.d = DOUBLEVALUE(vArgs->Value.aValue[i]);
  261.           break;
  262.         case VTYPE_STRING:
  263.           /* we allocate a one byte longer buffer and append a terminating zero */
  264.           Args[i].type = SBT_STRING;
  265.           Args[i].size=STRLEN(vArgs->Value.aValue[i]);/* size is w/o the terminating zero */
  266.           Args[i].v.s = alloc_Alloc(Args[i].size+1,pProgram->pMEM);
  267.           if( Args[i].v.s ){
  268.             memcpy(Args[i].v.s,STRINGVALUE(vArgs->Value.aValue[i]),Args[i].size);
  269.             Args[i].v.s[Args[i].size] = (char)0;
  270.             }
  271.           break;
  272.         default:
  273.           Args[i].type = SBT_UNDEF;
  274.           break;
  275.         }
  276.       }
  277.     }
  278.  
  279.   memory_ReleaseVariable(pProgram->pEXE->pMo,vArgs);
  280.   memory_ReleaseVariable(pProgram->pEXE->pMo,vReturn); /*Tomasz Lacki realised its missing*/
  281.   return iError;
  282.   }
  283.  

JRS

  • Guest
Re: SBT
« Reply #21 on: September 27, 2014, 08:42:19 PM »
Charles,

I think the ext. module API method of getting the arguments is okay and setting the value element of the argData array, What I don't see is the type of element or it's size being assigned. Is that done within the wrapper besHOOK_CALLSCRIBAFUNCTION?

With so many variadic functions used in SB, the transfer of data from arguments to SB data structures should be easier. The scriba_NewSbArgs function was a step in that direction by Peter but that assumes your interface is being done at the C level.


Charles Pegge

  • Guest
Re: SBT
« Reply #22 on: September 28, 2014, 07:42:17 PM »

Hi John,

I still can't get the hook functions pointer. - hacking into SB's data structures.

But I presume besHOOK_CALLSCRIBAFUNCTION works the same way as the CallArgEx function. SbData arrays can be created directly, setting data values and types directly - (except for SB strings!)

JRS

  • Guest
Re: SBT
« Reply #23 on: September 28, 2014, 07:59:33 PM »
Are you saying that SB doesn't require type or size elements of the sbData structure for LONG & REAL and only for STRING? With the besHOOK_CALLSCRIBAFUNCTION macro/function I can pass long, real, string and arrays giving it nothing other than a pointer to an argument. How can that be?


Charles Pegge

  • Guest
Re: SBT
« Reply #24 on: September 28, 2014, 08:13:01 PM »
No, You always have to set the type as well as the value (by union).

Similarly, on returned data, the type has to cased before looking at the value.

JRS

  • Guest
Re: SBT
« Reply #25 on: September 28, 2014, 08:22:59 PM »
The MyICall function in the trial extension module example that comes with SB to help explian how to use the ext, module API works perfect. It works just like the native ADDRESS /ICALL functions. If you look at the code I REM'ed out (ext. API) the only element of the sbData structure being set is the value. Somehow the besHOOK_CALLSCRIBAFUNCTION knows the type and size or if it is an array in whole being passed.  If you can tell me how I can use my passed pProgram pointer with besHOOK_CALLSCRIBAFUNCTION then all my problems are solved.


JRS

  • Guest
Re: SBT
« Reply #26 on: September 28, 2014, 10:48:11 PM »
Charles,

hook_CallScribaFunction is called by the macro besHOOK_CALLSCRIBAFUNCTION. This function exposes pExecuteObject pEo . Is this the same as the pProgram pointer I'm passing?

Charles Pegge

  • Guest
Re: SBT
« Reply #27 on: September 29, 2014, 01:48:29 AM »
scriba_callArgEx:

not the same, since it passes sbData structures, rather than individual values.

typedef struct _SbData {
  unsigned char type;
  unsigned long size;
  union {
    double d;
    long   l;
    unsigned char *s;
    } v;
  } SbData, *pSbData;


int (*scriba_CallArgEx)(pSbProgram pProgram, unsigned long lEntryNode, pSbData ReturnValue, unsigned long cArgs, pSbData Args);

     #define besScribaCallArgEx(F0,F1,F2,F3,F4) (pSt->scriba_CallArgEx((F0),(F1),(F2),(F3),(F4)))


besHOOK_CALLSCRIBAFUNCTION params: :o

typedef unsigned char BYTE, *PBYTE;

typedef struct _FixSizeMemoryObject {

  union _fsmoval{
    PBYTE  pValue;
    long   lValue;
    double dValue;
    struct _FixSizeMemoryObject **aValue;
    } Value;
  unsigned long Size;
  BYTE sType;
             
  BYTE vType;
  BYTE State;
 
 
 
 
  struct _FixSizeMemoryObject *next;     
  union {
    struct _FixSizeMemoryObject *prev;   
    struct _FixSizeMemoryObject **rprev;
    }link;
  long ArrayLowLimit, ArrayHighLimit;   
                                         
  } FixSizeMemoryObject, *pFixSizeMemoryObject,
    *MortalList, **pMortalList;


from your iCall:

besHOOK_CALLSCRIBAFUNCTION

  besHOOK_CALLSCRIBAFUNCTION(ulEntryPoint,
                             pArgument->Value.aValue,
                             besARGNR-1,
                             &FunctionResult);

It uses the pEo to access the pHookers function table

(pSt->pEo->pHookers->HOOK_CallScribaFunction(pSt->pEo,(ulEntryPoint),(pArgument->Value.aValue),((pParameters ? pParameters->ArrayHighLimit : 0)-1),(&FunctionResult)))


Unfortunately, I appear to have an incomplete pEo / ExecuteObject with many nulls, including the pHookers pointer.
« Last Edit: September 29, 2014, 03:15:30 AM by Charles Pegge »

JRS

  • Guest
Re: SBT
« Reply #28 on: September 29, 2014, 10:25:35 AM »
Quote
Unfortunately, I appear to have an incomplete pEo / ExecuteObject with many nulls, including the pHookers pointer.

I wouldn't mind if I had to call a function to build sbArgs from scriba but that doesn't seem possible other than from C. (no way to build args on the fly)

Peter said he wouldn't be able to look at this until this upcoming weekend. (plate overflowing) :-(



JRS

  • Guest
Re: SBT
« Reply #29 on: September 29, 2014, 01:10:56 PM »
I'm confused. If SB is passing mortal variables as arguments, why can't we used that definition with scriba_CallArgEx? How different is the argData and sbData in relationship to themselves? Everything we need is being passed. Why should it have to be redefined using something like scriba_NewSbArgs?

1. Native ICALL works fine,
2. Trial example MyICall works fine.
3. Missing embedded API arg to sbData routine.
« Last Edit: September 29, 2014, 02:01:18 PM by John »