Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Maury

macrumors 6502
Original poster
Mar 25, 2008
459
26
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:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms710297(v=vs.85).aspx

My code is...
Code:
    SQLCHAR szName[SQL_MAXIMUM_CATALOG_NAME_LENGTH];
    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?
 
Last edited by a moderator:
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.
 
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
Code:
SQLHDBC ConnectionHandle
not
Code:
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.
 
stringWithCString:encoding: is declared as:

Code:
+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc

So why are you passing

Code:
&szName

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)?
 
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.

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.

Ok I'd like to do this now, do you have a pointer to the doc for this? My google-fu has failed me.
 
@ ScoobyMcDoo & robbieduncan

Code:
#include <stdio.h>

#define SQL_MAXIMUM_CATALOG_NAME_LENGTH  20

typedef  unsigned char  SQLCHAR;

int main( int argc, const char * argv[] )
{
	SQLCHAR szName[ SQL_MAXIMUM_CATALOG_NAME_LENGTH ];
	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):
Code:
 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.

----------

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

Glad it worked out.


Ok I'd like to do this now, do you have a pointer to the doc for this? My google-fu has failed me.
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.
 
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.