6

I have a function that returns an NSError object by reference:

NSData *foo(NSData *foo, NSError *__autoreleasing *outError);

This function uses an API that takes a pointer to storage for a CFErrorRef. I'd like to just pass outError to the underlying function directly, but I can't figure out the correct combination of declaration keywords and cast keywords to make clang agree with that plan. Is there one?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • cheat? blah((CFErrorRef*)(void *)error); – Bored Astronaut Dec 15 '11 at 22:29
  • ... otherwise it's just a two-step process. I think the compiler's pretty clear that it needs you to make a local declaration. I think it can't do its bookkeeping properly, otherwise. ( CFErrorRef error2; blah(&error2); *error = (__bridge NSError *)error2; -- I guess that's what you're trying to avoid). – Bored Astronaut Dec 15 '11 at 22:50
  • Indeed, I'd prefer not to have to hot-potato the error object back to the caller myself. – Peter Hosey Dec 15 '11 at 23:18

2 Answers2

4

If you look at the clang notes for __autoreleasing it mentions that the magic happens at assignment time, which means that automatic casting can't help here. You need to actually make the assignment using a temporary variable as mentioned in the comments on the original post.

cobbal
  • 69,903
  • 20
  • 143
  • 156
0

Try this:

NSError+CFErrorRef.h

@interface NSError (CFErrorRef)

- (CFErrorRef) cferror;

@end

NSError+CFErrorRef.m

#import "NSError+CFErrorRef.h"

@implementation NSError (CFErrorRef)

- (CFErrorRef) cferror
{
    CFStringRef domain = (CFStringRef) self.domain;

    CFDictionaryRef userInfo = (__bridge CFDictionaryRef) self.userInfo;

    return CFErrorCreate(kCFAllocatorDefault, domain, self.code, userInfo);
}

@end

I wrote a quick little unit test to verify everything converted over and it appears to be working correctly. Then you can just perform the following selector on your NSError object

CFErrorRef e = [error cferror];
jerrylroberts
  • 3,419
  • 23
  • 22
  • 1
    It isn't necessary to create a CFError object from an NSError object, for two reasons: (1) The function I'm calling returns a CFError object. (2) CFError and NSError are toll-free bridged, so the CFError object is an NSError object already. What I'm looking for is a way to convince the compiler to let me pass my NSError out-pointer to the underlying function's CFError out-pointer argument without either giving me an error or leaking it. – Peter Hosey Dec 19 '11 at 19:36
  • Oh I see, I was just going strictly off the subject line. That one is a little harder to prove in isolation hehehe – jerrylroberts Dec 19 '11 at 19:52