Something you might be able to answer


(Philippe Hausler) #1

So there are a couple of ways objects can be bridged:

1) has-a style bridges - RunLoop and CFRunLoop for example. The only association is where RunLoop contains a CFRunLoop and there is a method to fetch the CFRunLoop out of the RunLoop. Some times this relationship is not public.

2) is-a style bridges - NSCFString and CFString for example. These are where the structural size and layout of the objects are identical. So when casting the only change is a re-interpretation of the type and the underlying data structure backing the object is exactly the same.

3) toll-free bridges - NSString and CFString for example. CF can take NSStrings because the methods that transact upon CFStrings all check to determine if the object being passed is a subclass of NSString or if it is a NSCFString, in the NSString subclass cases it will dispatch calls out to the subclass to specific funnel points such that it can reasonably transact upon that object.

4) Compiler generated struct to reference bridges - NSString and String. When the translation occurs the compiler emits a call to a method on String to convert NSString to String. This is just a specialized and automatically generated form of style 1

The styles 1, 2 and 3 work for swift-corelibs-foundation, however 4 is disabled for linux even though we have both the reference types and the structural types.

On Darwin CFReadStream is actually a NSCFInputStream (which is a subclass of NSInputStream) but currently in swift-corelibs-foundation CFReadStream is a NSCFType (I would consider that discrepancy an incomplete point of swift-corelibs-foundation) with an ivar of a CFReadStream. So what would need to be done is that InputStream and OutputStream would need to be made conditionally abstract and the ivar layout would need to exactly mimic the layout of the CF counterpart. Two new subclasses would need to be made to dispatch back into CF the functionality for streams created from CF and dispatching methods would need to be made. Doing this would make InputStream and OutputStream more like NSString (which might be a decent place to take a look at how it works).

Let me know if there is anything I can help clear up on more.

···

On Sep 20, 2016, at 11:29 PM, Dave Abrahams <dabrahams@apple.com> wrote:

From: Bouke Haarsma via swift-users <swift-users@swift.org>
Subject: How to bridge between CoreFoundation and SwiftFoundation on Linux?
Date: September 20, 2016 at 9:38:54 PM PDT
To: swift-users@swift.org
Reply-To: Bouke Haarsma <bouke@haarsma.eu>

Hi all,

When working with CoreFoundation objects (e.g. CFReadStream,
CFWriteStream) it isn't immediately obvious to me how to bridge them to
SwiftFoundation counterparts (InputStream / OutputStream).

The following works on OSX, but doesn't work on Linux;

   let readStream: CFReadStream = ...
   readStream as InputStream
   // error: cannot convert value of type 'CFReadStream' to expected
argument type 'InputStream'

In some other places I need to bridge a String to a CFString, the
following works on OSX, but doesn't work on Linux;

   let string: String = ...
   string as CFString
   // error: error: 'String' is not convertible to 'CFString'; did you
mean to use 'as!' to force downcast?

Thanks.

--
-Bouke

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
-Dave