What is up.
RSS icon Email icon Home icon
  • Working with Pascal Strings in Cocoa

    Posted on August 23rd, 2007 Alan 2 comments

    In trying to access information from a quicktime file I came across my first pascal string (pstring).  Trying to copy this string using strncpy or NSString:stringWithCString did not work so I looked at the memory and saw a number as the first byte.  I recognized this as a pascal string so I searched on conversion from pstring to NSString and found this:

    http://www.omnigroup.com/mailman/archive/macosx-dev/2001-August/030492.html
    http://developer.apple.com/documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html#//apple_ref/c/func/CFStringCreateWithPascalString

    The documentation for CFString states: "in a method where you see an NSString * parameter, you can pass in a CFStringRef" but the compiler complained so as in the example code linked above, I resorted to using the NSString:stringWithFormat. My first thought was to simply use NSString:stringWithString.

    Here is the wrapper function I came up with:

    -(NSString*)NSStringFromPString:(unsigned char*) pstring
    {
        CFStringRef strRef = CFStringCreateWithPascalString (NULL, pstring, kCFStringEncodingMacRoman);
        return [NSString stringWithFormat:@"%@",strRef];
    }

    Update 8/24/07: It seems the error when using stringWithString has something to do with what source is being compiled.  If it is in an .mm file (enables C++ compatibility?) I get the error:

    error: cannot convert ‘const __CFString*’ to ‘NSString*’ in argument passing

    but if compiled in an .m file it works fine.  It appears that in the former case, the compiler is being stricter, though a forced cast will eliminate the error message.

     

    2 responses to “Working with Pascal Strings in Cocoa”

    1. NSString and CFString are toll-free bridged, which means they’re really the same object underneath—but as you discovered, the compiler doesn’t know this. Rather than creating a new string from your old one, however, you can just cast a CFStringRef to an NSString * and vice versa (which makes the compiler happy without adding any extra instructions at run-time).

      For example, you might rewrite the above method like this:

      + (NSString*)NSStringFromPString:(unsigned char *)pstring
      {
          CFStringRef strRef = CFStringCreateWithPascalString (NULL, pstring, kCFStringEncodingMacRoman);
          NSString *string = (NSString *)strRef;
          return [string autorelease];
      }

      (Note the final call to -autorelease: CFStringCreate… creates a retained string which you need to release or autorelease at some point, and by convention a method without “new” or “retained” in the name returns an autoreleased object. Of course, none of that matters if you choose to use garbage collection in Leopard.)

      Hope this helps!

    2. Thanks Ken. I came to a similar conclusion after speaking with a friend. Thanks for your detailed comment and for taking the time to help. I of course appreciate having found the helpful code to begin with in your newsgroup.

    Leave a reply

    You must be logged in to post a comment.