Mr Aleph
Mr Aleph

Reputation: 1895

Converting a CFStringRef to char *

I am getting a CFStringRef out of a CFDictionaryRef using CFDictionaryGetValue.

I've been trying to convert the CFStringRef to a char* using CFStringGetCString or CFStringGetCStringPtr and they either return a NULL or it crashes.

Is there a way to do this? How?

Thank you.

EDIT: sample code:

SecStaticCodeRef staticCode;
CFDictionaryRef information;
SecCSFlags flags = kSecCSInternalInformation
            | kSecCSSigningInformation
            | kSecCSRequirementInformation
            | kSecCSInternalInformation;    
CFURLRef pathURL = NULL;
CFStringRef pathStr = NULL;
CFStringRef uniqueid;
char* str = NULL;
CFIndex length;


pathStr = CFStringCreateWithCString(kCFAllocatorDefault,  
                                    filename, kCFStringEncodingUTF8);    
pathURL = CFURLCreateWithString(kCFAllocatorDefault, pathStr, NULL);
SecStaticCodeCreateWithPath(pathURL, kSecCSDefaultFlags, &staticCode);
SecCodeCopySigningInformation(staticCode, flags, &information);      

uniqueid = (CFStringRef) CFDictionaryGetValue(information, kSecCodeInfoUnique);

// how do I convert it here to char *?
length = CFStringGetLength(uniqueid);
str = (char *)malloc( length + 1 );
CFStringGetCString(uniqueid, str, length, kCFStringEncodingUTF8);

printf("hash of signature is %s\n", str);

CFRelease(information);
CFRelease(staticCode);

Upvotes: 21

Views: 36079

Answers (6)

andrewchan2022
andrewchan2022

Reputation: 5300

very simple:

CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
const char *path = CFStringGetCStringPtr(cfStrRef, encodingMethod);

Upvotes: 4

Rob Napier
Rob Napier

Reputation: 299345

From the Chapter 17 example code in iOS:PTL.

char * MYCFStringCopyUTF8String(CFStringRef aString) {
  if (aString == NULL) {
    return NULL;
  }

  CFIndex length = CFStringGetLength(aString);
  CFIndex maxSize =
  CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
  char *buffer = (char *)malloc(maxSize);
  if (CFStringGetCString(aString, buffer, maxSize,
                         kCFStringEncodingUTF8)) {
    return buffer;
  }
  free(buffer); // If we failed
  return NULL;
}

The resulting buffer must always be freed (which is why Copy is in the name). The linked example code also has a slightly faster version that uses a buffer you provide.

Upvotes: 30

evandrix
evandrix

Reputation: 6210

why not simply: printf("%s\n", CFStringGetCStringPtr(uniqueid, kCFStringEncodingUTF8));?

Upvotes: 6

Sahil Mahajan
Sahil Mahajan

Reputation: 3990

There is an another one line solution for the same problem:

char * myCString =  [(__bridge NSString *)myCfstring UTF8String];

Happy Coding :)

Upvotes: 12

bobobobo
bobobobo

Reputation: 67254

Another answer:

const char *cs = CFStringGetCStringPtr( cfString, kCFStringEncodingMacRoman ) ;
puts( cs ) ; // works

I can't find the reason why kCFStringEncodingUTF8 gives NULL, but kCFStringEncodingMacRoman seems to work fine.

Upvotes: 17

MrDaniel
MrDaniel

Reputation: 610

From the String Programming Guide for Core Foundation Documentation. Here is how you get the Contents of a CFStringRef as a C String.

I have made a modification to it as so, this should do what you are looking for.

#include <CoreFoundation/CoreFoundation.h>


CFStringRef str;
//Removed CFRange
const char *bytes; //This is where the conversion result will end up.



str = CFSTR("You Want this String!\n"); //Changed this part

bytes = CFStringGetCStringPtr(str, kCFStringEncodingMacRoman);



if (bytes == NULL) 
{
    //Adding in getting the size
    CFIndex stringLengthIndex = CFStringGetLength(str);

    //Converted index (signed long ) to int
    char localBuffer[(int) stringLengthIndex];

    Boolean success;

    success = CFStringGetCString(str, localBuffer, stringLengthIndex, kCFStringEncodingMacRoman);

}
//At this point the "bytes" variable should contain your C string copied from the provided CFStringRef 

Upvotes: 1

Related Questions