WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: JTaylor on May 12, 2015, 06:31:06 AM

Title: Extender SDK - Returning an Array
Post by: JTaylor on May 12, 2015, 06:31:06 AM
Which macro should I use to return an array from an Extender?   What form does the data need to be in when returning?   Sample code always appreciated :-)

Thanks.

Jim
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 12, 2015, 07:05:44 AM
Thought I figured it out but getting gibberish.   Guess that is better than an outright error :-)

Jim
Title: Re: Extender SDK - Returning an Array
Post by: td on May 12, 2015, 07:13:27 AM
I don't believe there is a macro for returning an WIL array.  You need to fill a LPVIPERVAR structure with the appropriate values and call the ViperCallback function using the function pointer in lpViperCallBack.  That is mostly what the 'RETURN' macros do.

Any examples we might have are written using regrettably obtuse C++ templates that would require some understanding of generic programming to decipher but the basic concept is fairly straight forward and the existing macros are the best example.  The DllArrayServices extender interface callback does all the heavy lifting with regard to initializing your ViperVar (LPVIPERVAR) structure that you pass back to the interpreter via the lpViperCallBack function pointer.
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 12, 2015, 08:11:26 AM
Assuming I am somewhat on the right track...to what would the "lpstr=str" need to be changed?  Is the rest correct?

lpViperCallback(((lpViperReturn->lpstr=str)   +(lpViperReturn->inittype=VARTYPE_ARRAY))   ?RESULT_SUCCESS:RESULT_SUCCESS, ViperInterfaceVersion, lpViperStruct, lpViperReturn)


Jim
Title: Re: Extender SDK - Returning an Array
Post by: td on May 12, 2015, 09:17:52 AM
Assuming you have a properly created ViperVar variable from a call to
vipervar ArrayVar
lpViperStruct->lpfnDllArrayServices(.., &ArrayVar....)

then you can simply assign all elements of array variable structure to the return variable structure.

*lpViperReturn = ArrayVar

And assuming the ArrayVar is valid, pass the shallow copy of the  array variable back to the interpreter.

return lpViperCallback(RESULT_SUCCESS, ViperInterfaceVersion, lpViperStruct, lpViperReturn);
Title: Re: Extender SDK - Returning an Array
Post by: td on May 12, 2015, 09:30:02 AM
Note that you are responsible for freeing the resources allocated to your local copy of the array variable so you will need to hang on to your copy and call lpfnDllArrayServices with request 4 to clean up.
Title: Re: Extender SDK - Returning an Array
Post by: td on May 12, 2015, 12:00:53 PM
Correction:  You don't need to clean up your local copy of an array variable with  lpfnDllArrayServices with request 4 when you pass the array back the interpreter.  The interpreter will take care of it for you.   
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 12, 2015, 03:36:20 PM
I hate to ask but would you PLEASE take pity on me and fix the mess below so it will return an array?  I realize it would help if I knew what I was doing but I am far from that point and my hours of work, while somewhat educational, doesn't seem to be doing much to solve the problem.  At one point I was getting a zero(success) response from the ArrayService call but WinBatch still told me it wasn't an array or some such error.  I finally created a function to simply try to get an array returned rather than the data I want in the array.  My latest iteration is below.   Currently I either get a 7 or a 10 response, depending on what I do with lpBuf.  Thanks.

Jim

Code (winbatch) Select


  vipervar myarr;
  LONG lpBuf;
  LONG afun = 2;

//  LONG DllArrayServices(HGLOBAL hBatData,  &myarr, UINT uVarSize, LPBYTE lpBuf, UINT uBufSize, LONG afun);
     int ret = lpViperStruct->lpfnDllArrayServices(lpViperStruct->hBatData, &myarr, sizeof(vipervar),  (LPBYTE) lpBuf, sizeof(lpBuf), afun);

     MyLtoa(ret,szWork,10);
     MessageBox(hWnd, szWork, "Repsponse Code", MB_OK);

 
  myarr.x      = 111;
  myarr.lpstr  = "Hello";
  myarr.lpstr  = "2015";
  myarr.lpstr  = "2015";
  myarr.lpstr  = "2015";
  myarr.x      = 222;
  myarr.x      = 32;

      *lpViperReturn = myarr;  
 
 
      return lpViperCallback(RESULT_SUCCESS, ViperInterfaceVersion, lpViperStruct, lpViperReturn);

Title: Re: Extender SDK - Returning an Array
Post by: td on May 13, 2015, 08:19:24 AM
First, you need to go to the addons.h file and examine what the DllArrayServices function is expecting for parameters when you use it to create an array.  Once you have that figured out, take a look at the DllArrHandler function in addons.h.  This is the function you use to set and get individual elements from the WIL array after you created it with DllArrayServices. Notice that  it states
about the nrequest parameter.

2  =  set (and clear) value                   (vv = value to set)

Also notice that the element value to set (vv) must be a in a vipervar.  So you need to place the array element value in a vipervar and call the  DllArrhandler with request 2 to add a value to the specified  array location. You specify the elements's location in the array using the subscript parameters of the function.
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 13, 2015, 10:36:50 AM
Yes.  Have spent a few hours looking at Addons.h and also have the source for the Array Extender and have been perusing that for a clear example.   I'll go back to beating my head against the wall for a few more hours before probably asking the same question again :-)    The vv info is helpful.  Saw that in the Array Extender and thought it was important but wasn't sure in what way.

One thing that would be helpful though...what would I use for the lpBuf?  Not clear what data I will be buffering.  Just a row?  The entire array?  Something else entirely?   Can't recreate whatever I did before to get a successful response on the DllArrayServices call.   Not that it means I was doing it right but I counted it a small victory at the time.

Thanks.

Jim
Title: Re: Extender SDK - Returning an Array
Post by: td on May 13, 2015, 11:11:37 AM
From addons.h DllArrayServices parameter descriptions:

lpBuf     =  buffer for input or output, depending on request (cast to LPBYTE)

and

nRequest  =  operation to perform:
    1  =  get array info    (lpBuf = pointer to DLLARRAYSERVICES1 structure)
    2  =  create array      (lpBuf = pointer to DWORD[5] containing array dimensions <<<<-----------
    3  =  initialize array  (lpBuf = vipervar containing value to set)
    4  =  free array        (lpBuf = 0)
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 13, 2015, 11:40:51 AM
If I could read it would probably help  ;)

Thanks.

Jim
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 13, 2015, 12:36:34 PM
I think I just did something REALLY wrong because it works :)

If I keep at this for another 10 years or so it might start making sense.

Thank you VERY much.

Jim
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 15, 2015, 11:00:57 AM
Wondering if someone could point out my problem.   The value before returning from GetWBTime() is correct so I know that value I am passing is correct and everything works.   It is during the "return" that I end up with gibberish.  Have spent a few hours going nowhere so thought I would ask.  Thanks.

Jim


Give this as a prototype:

    LPSTR NEARPASCAL GetWBTime(FILETIME);


Then this call:

LPSTR wbtimec         = "";

wbtimec = GetWBTime(fcreate);

to

Code (winbatch) Select


LPSTR NEARPASCAL GetWBTime(FILETIME fdate)
{

SYSTEMTIME st;
char display[512]    = "";
        char wbtime[19]      = "";
     
        FileTimeToLocalFileTime( &fdate, &fdate );
        FileTimeToSystemTime( &fdate, &st );

        GetDateFormat (LOCALE_USER_DEFAULT, NULL, &st, "yyyy:MM:dd:",  display, 512 );
        strcpy (wbtime, display);
        GetTimeFormat (LOCALE_USER_DEFAULT, NULL, &st, "HH:mm:ss",     display, 512 );
        strcat (wbtime, display);

if (display && display[0] == '\0') {wbtime[0] = (char)"";}
MessageBox(NULL,wbtime,"AS IS",MB_OK);

return (LPSTR) wbtime;

}

Title: Re: Extender SDK - Returning an Array
Post by: td on May 15, 2015, 12:59:03 PM
Yikes. You're returning a pointer to a stack variable.  Can't do that.  You need to either place your return string into dynamically allocated memory and return the pointer or pass in a pointer to a buffer big enough to hold your result.
Title: Re: Extender SDK - Returning an Array
Post by: JTaylor on May 15, 2015, 01:20:53 PM
Figured it was something like that but just haven't figured out the right combination....to borrow some words..."I know 1,000 ways how NOT to do it" :-)

I'm sure your guidance will get me there though...back to it....thanks again.

Jim