OS X Externals

Mark Wieder mwieder at ahsoftware.net
Wed Oct 13 19:39:51 EDT 2004


Frank-

A few things here:

First off, the runrev engine needs to clean the stack when you return
from an external call. This involves deleting the arguments and
freeing up the allocated memory. Instead of
           *retstring = 0;

you should be using
           *retstring = calloc(1,1);
to avoid having the engine try to free up a null pointer. Freeing a
null pointer is defined as a NOP by the standard, but it's a bad idea
to rely on it.

Second, you might try replacing
        *retstring = buffer;

with
        *retstring = istrdup(buffer);
        free (buffer);

I think you're OK on this one since you're mallocing memory and not
freeing it, forcing the engine to do this for you, but I'm not sure.

Third, it's generally good form to check the result value from a
malloc() call to ensure that it worked.
         buffer = (char *)malloc(10 + (rdata.length * 5));
         if (NULL == buffer)
         {
             *retstring = calloc(1,1);
             *pass = False;
             *error = True;
             return;
         }

And lastly, you might also check rdata before using it. This is
related to the malloc() call above. If your call to GetVariableEx
fails then rdata.length and rdata.sptr will be undetermined. Your
malloc() call may or may not return anything useful, and your buffer
fills will be getting memory from somewhere else from where you expect
them to.

     if (NULL != rdata.sptr)
     {
        // etc.

I'm not sure any of these have any bearing on why you're seeing
different results.

Also... I found an error in the sdk where GetVariableEx is listed as
one of the functions that allocates memory for a return variable.
That's not the case, so you don't have to free up the return value -
it's actually a void function. Just FYI.

Wednesday, October 13, 2004, 2:02:29 PM, you wrote:

FDEJ> This simply takes each character and yields a zero-padded, three-octet
FDEJ> number preceded by two backslash '\' characters.  My C equivalent
FDEJ> reads:

FDEJ> void dbBLOB(char *args[], int nargs, char **retstring, Bool *pass, Bool
FDEJ> *error)
FDEJ> {
FDEJ>         int retvalue;
FDEJ>         MCstring rdata;
FDEJ>      char *buffer;
FDEJ>         int i, j = 0;
        
FDEJ>         if(nargs != 1)
FDEJ>         {
FDEJ>             *retstring = 0;
FDEJ>                 *pass = False;
FDEJ>                 *error = True;
FDEJ>                 return;
FDEJ>         }
        
FDEJ>         GetVariableEx(args[0], "", &rdata, &retvalue);
        
FDEJ>         buffer = (char *)malloc(10 + (rdata.length * 5));
FDEJ>         *pass = False;
FDEJ>         *error = False;
        
FDEJ>         buffer[j++] = '\'';
        
FDEJ>         for(i = 0; i < rdata.length; i++)
FDEJ>         {
FDEJ>                 buffer[j++] = '\\';
FDEJ>                 buffer[j++] = '\\';
FDEJ>                 sprintf(&(buffer[j]), "%03o", rdata.sptr[i]);
FDEJ>                 j += 3;
FDEJ>         }
        
FDEJ>         buffer[j++] = '\'';
FDEJ>         buffer[j++] = ':';
FDEJ>         buffer[j++] = ':';
FDEJ>         buffer[j++] = 'b';
FDEJ>         buffer[j++] = 'y';
FDEJ>         buffer[j++] = 't';
FDEJ>         buffer[j++] = 'e';
FDEJ>         buffer[j++] = 'a';
FDEJ>         buffer[j] = 0;
        
FDEJ>         *retstring = buffer;
FDEJ> }


-- 
-Mark Wieder
 mwieder at ahsoftware.net



More information about the use-livecode mailing list