Calling into C code

Discussion in 'Mac Programming' started by Maury, Jun 15, 2012.

  1. Maury, Jun 15, 2012
    Last edited by a moderator: Jun 15, 2012

    macrumors 6502

    Mar 25, 2008
    This is noob, I know, but I haven't touched basic C in years...

    I'm trying to call into the ODBC call "SQLGetConnectAttr", as documented here:

    My code is...
        SQLINTEGER iLen;
        SQLINTEGER nResult;
        nResult = SQLGetConnectAttr(&hdbc, SQL_ATTR_CURRENT_CATALOG, &szName, SQL_MAXIMUM_CATALOG_NAME_LENGTH, &iLen);
        if (nResult != SQL_SUCCESS)
            // do something!
        return [NSString stringWithCString:(char *)&szName encoding:NSASCIIStringEncoding];
    The code runs without errors, but I'm getting gooblygook output. I suspect I'm declaring or passing the buffer incorrectly? That I should or should not have a * and/or & somewhere?
  2. macrumors 65816

    Nov 26, 2007
    Austin, TX
    I think your third parameter should be szName rather than &szName. The API is asking for a pointer to a buffer. You are supplying it a pointer to a pointer to a buffer.
  3. macrumors 604

    Aug 9, 2009
    1. Please show the type of the variable hdbc. If its type is SQLHDBC, then your first function arg is wrong. The declared type is
    SQLHDBC ConnectionHandle
    SQLHDBC * ConnectionHandle
    There should have been a compiler warning about mismatched types. If not, you should turn on strict arg-type checking for functions, and pay attention to all warnings.

    2. If nResult isn't successful, does the block return or otherwise break sequential flow? Because if it doesn't, it will fall thru to NSString stringWithCString:, which I'm pretty sure won't work.

    3. Is the string data really in the ASCII encoding? ASCII is a 7-bit code. If there are any bytes in the range 0x80-0xFF, it ain't ASCII.
  4. Moderator emeritus


    Jul 24, 2002
    stringWithCString:encoding: is declared as:

    + (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc
    So why are you passing

    Which you are casting to be a char*? What does the & operator do? Does this result in a pointer? Or did you already have a pointer before you used the & operator (hint are arrays really pointers)?
  5. thread starter macrumors 6502

    Mar 25, 2008
    Thank you so much, your suggestion to remove the & on hdbc nailed it! Ugg, so nice to see working data.

    I know I have to re-learn all these pointer passing rules, it can be very frustrating to track these down.

    Ok I'd like to do this now, do you have a pointer to the doc for this? My google-fu has failed me.
  6. macrumors 604

    Aug 9, 2009
    @ ScoobyMcDoo & robbieduncan

    #include <stdio.h>
    typedef  unsigned char  SQLCHAR;
    int main( int argc, const char * argv[] )
    	int nums[ 10 ];
    	printf( " szName: %p\n", szName );
    	printf( " &szName: %p\n", &szName );
    	printf( " &szName[0]: %p\n", &szName[0] );
    	printf( " nums: %p\n", nums );
    	printf( " &nums: %p\n", &nums );
    	printf( " &nums[0]: %p\n", &nums[0] );
    Output (64-bit):
     szName: 0x7fff5fbff890
     &szName: 0x7fff5fbff890
     &szName[0]: 0x7fff5fbff890
     nums: 0x7fff5fbff860
     &nums: 0x7fff5fbff860
     &nums[0]: 0x7fff5fbff860

    In C, the unadorned name of an array is a constant pointer to the first element of that array. Since it's a constant, it can't have its address taken (prefix & operator). The compiler simply gives the address of the first array element, effectively ignoring the &. There was a time when C compilers complained about & prefixing array names, but that was long, long ago.

    If szName were declared as pointer type, then it can have its address taken. The code illustrating this is left as an exercise for the reader.


    Glad it worked out.

    Your OS version? Xcode version? Development tools (Xcode, make, something else)?

    -Wall should turn on most warnings. Otherwise consult the man page for gcc and look for the word prototype.
  7. macrumors 65816

    Nov 26, 2007
    Austin, TX
    Wow, I forgot all about that. Made me curious, so I looked it up in my trusty 1st edition K&R and sure enough is says that taking the address of an array is illegal.

Share This Page