5.16 Objective-C FFI

► |  | The Racket Foreign Interface

1 | Overview
2 | Loading Foreign Libraries
3 | C Types
4 | Pointer Functions
5 | Derived Utilities
6 | Miscellaneous Support
7 | Unexported Primitive Functions
| Bibliography
| Index

▼ | 5 | Derived Utilities

5.1 | Safe Homogenous Vectors
5.2 | Safe C Vectors
5.3 | Tagged C Pointer Types
5.4 | Serializable C Struct Types
5.5 | Static Callout and Callback Cores
5.6 | Defining Bindings
5.7 | Allocation and Finalization
5.8 | Custodian Shutdown Registration
5.9 | Atomic Execution
5.10 | Speculatively Atomic Execution
5.11 | Thread Scheduling
5.12 | Ports
5.13 | Process-Wide and Place-Wide Registration
5.14 | Operating System Threads
5.15 | Garbage Collection Callbacks
5.16 | Objective-C FFI
5.17 | Cocoa Foundation
5.18 | COM (Common Object Model)
5.19 | File Security-Guard Checks
5.20 | Windows API Helpers
5.21 | Virtual Machine Primitives

► | 5.16 | Objective-C FFI

5.16.1 | FFI Types and Constants
5.16.2 | Syntactic Forms and Procedures
5.16.3 | Raw Runtime Functions
5.16.4 | Legacy Library

On this page:

5.16.1 FFI Types and Constants
_ id
_ Class
_ Protocol
_ SEL
_ BOOL
YES
NO
5.16.2 Syntactic Forms and Procedures
tell
tellv
import-class
import-protocol
define-objc-class
define-objc-mixin
self
super-tell
get-ivar
set-ivar!
selector
objc-is-a?
objc-subclass?
objc-get-class
objc-set-class!
objc-get-superclass
objc-class-has-instance-method?
objc-dispose-class
objc-block
objc-block-function-pointer
with-blocking-tell
5.16.3 Raw Runtime Functions
objc_ look Up Class
objc_ get Protocol
sel_ register Name
objc_ allocate Class Pair
objc_ register Class Pair
object_ get Class
class_ get Superclass
class_ add Method
class_ add Ivar
object_ get Instance Variable
object_ set Instance Variable
_ Ivar
objc_ msg Send/ typed
objc_ msg Send Super/ typed
make-objc_ super
_ objc_ super
objc_ msg Send/ typed/ blocking
objc_ msg Send Super/ typed/ blocking
5.16.4 Legacy Library
objc-unsafe!

Racket
top contents ← prev up next →

### 5.16 Objective-C FFI🔗ℹ

(require ffi/unsafe/objc) | package: base

The ffi/unsafe/objc library builds on ffi/unsafe to support interaction with Objective-C.

The library supports Objective-C interaction in two layers. The upper layer provides syntactic forms for sending messages and deriving subclasses. The lower layer is a thin wrapper on the Objective-C runtime library functions. Even the upper layer is unsafe and relatively low-level compared to normal Racket libraries, because argument and result types must be declared in terms of FFI C types (see Type Constructors).

#### 5.16.1 FFI Types and Constants🔗ℹ

> value _id : ctype?

The type of an Objective-C object, an opaque pointer.

> value _Class : ctype?

The type of an Objective-C class, which is also an _id.

> value _Protocol : ctype?

The type of an Objective-C protocol, which is also an _id.

> value _SEL : ctype?

The type of an Objective-C selector, an opaque pointer.

> value _BOOL : ctype?

The Objective-C boolean type. Racket values are converted for C in the usual way: #f is false and any other value is true. C values are converted to Racket booleans.

> value YES : boolean?

Synonym for #t

> value NO : boolean?

Synonym for #f

#### 5.16.2 Syntactic Forms and Procedures🔗ℹ

> syntax (tell result-type obj-expr method-id)
> (tell result-type obj-expr arg ...)
> result-type |  | = |  |
> |  | | |  | #:type ctype-expr
> arg |  | = |  | method-id arg-expr
> |  | | |  | method-id #:type ctype-expr arg-expr

Sends a message to the Objective-C object produced by obj-expr. When a type is omitted for either the result or an argument, the type is assumed to be _id, otherwise it must be specified as an FFI C type (see Type Constructors).

If a single method-id is provided with no arguments, then method-id must not end with :; otherwise, each method-id must end with :.

Examples:

> > (tell NSString alloc)
> #<cpointer:id>
> > (tell (tell NSString alloc)
> initWithUTF8String: #:type _string "Hello")
> #<cpointer:id>

> syntax (tellv obj-expr method-id)
> (tellv obj-expr arg ...)

Like tell, but with a result type _void.

> syntax (import-class class-id ...)

Defines each class-id to the class (a value with FFI type _Class) that is registered with the string form of class-id. The registered class is obtained via objc_lookUpClass.

Example:

> > (import-class NSString)

A class accessed by import-class is normally declared as a side effect of loading a foreign library. For example, if you want to import the class NSString on Mac OS, the "Foundation" framework must be loaded, first. Beware that if you use import-class in DrRacket or a module that requires racket/gui/base, then "Foundation" will have been loaded into the Racket process already. To avoid relying on other libraries to load "Foundation", explicitly load it with ffi-lib:

> > (ffi-lib
> "/System/Library/Frameworks/Foundation.framework/Foundation")
> > (import-class NSString)

> syntax (import-protocol protocol-id ...)

Defines each protocol-id to the protocol (a value with FFI type _Protocol) that is registered with the string form of protocol-id. The registered class is obtained via objc_getProtocol.

Example:

> > (import-protocol NSCoding)

> > syntax
> > (define-objc-class class-id superclass-expr
> > maybe-mixins
> > maybe-protocols
> > [field-id ...]
> > method ...)
> maybe-mixins |  | = |  |
> |  | | |  | #:mixins (mixin-expr ...)
> maybe-protocols |  | = |  |
> |  | | |  | #:protocols (protocol-expr ...)
> method |  | = |  | (mode maybe-async result-ctype-expr (method-id) body ...+)
> |  | | |  | (mode maybe-async result-ctype-expr (arg ...+) body ...+)
> mode |  | = |  | +
> |  | | |  | -
> |  | | |  | +a
> |  | | |  | -a
> maybe-async |  | = |  |
> |  | | |  | #:async-apply async-apply-expr
> arg |  | = |  | method-id [ctype-expr arg-id]

Defines class-id as a new, registered Objective-C class (of FFI type _Class). The superclass-expr should produce an Objective-C class or #f for the superclass. An optional #:mixins clause can specify mixins defined with define-objc-mixin. An optional #:protocols clause can specify Objective-C protocols to be implemented by the class, where a #f result for a protocol-expr is ignored.

Each field-id is an instance field that holds a Racket value and that is initialized to #f when the object is allocated. The field-ids can be referenced and set! directly when the method bodys. Outside the object, they can be referenced and set with get-ivar and set-ivar!.

Each method adds or overrides a method to the class (when mode is - or -a) to be called on instances, or it adds a method to the meta-class (when mode is + or +a) to be called on the class itself. All result and argument types must be declared using FFI C types (see Type Constructors). When mode is +a or -a, the method is called in atomic mode (see _cprocedure). An optional #:async-apply specification determines how the method works when called from a foreign thread in the same way as for _cprocedure.

If a method is declared with a single method-id and no arguments, then method-id must not end with :. Otherwise, each method-id must end with :.

If the special method dealloc is declared for mode -, it must not call the superclass method, because a (super-tell dealloc) is added to the end of the method automatically. In addition, before (super-tell dealloc), space for each field-id within the instance is deallocated.

Example:

> > (define-objc-class MyView NSView
> [bm] ; <- one field
> (- _racket (swapBitwmap: [_racket new-bm])
> (begin0 bm (set! bm new-bm)))
> (- _void (drawRect: [_NSRect exposed-rect])
> (super-tell drawRect: exposed-rect)
> (draw-bitmap-region bm exposed-rect))
> (- _void (dealloc)
> (when bm (done-with-bm bm))))

Changed in version 6.90.0.26 of package base: Changed #:protocols handling to ignore #f expression results.

> > syntax
> > (define-objc-mixin (class-id superclass-id)
> > maybe-mixins
> > maybe-protocols
> > [field-id ...]
> > method ...)

Like define-objc-class, but defines a mixin to be combined with other method definitions through either define-objc-class or define-objc-mixin. The specified field-ids are not added by the mixin, but must be a subset of the field-ids declared for the class to which the methods are added.

> syntax self

When used within the body of a define-objc-class or define-objc-mixin method, refers to the object whose method was called. This form cannot be used outside of a define-objc-class or define-objc-mixin method.

> syntax (super-tell result-type method-id)
> (super-tell result-type arg ...)

When used within the body of a define-objc-class or define-objc-mixin method, calls a superclass method. The result-type and arg sub-forms have the same syntax as in tell. This form cannot be used outside of a define-objc-class or define-objc-mixin method.

> syntax (get-ivar obj-expr field-id)

Extracts the Racket value of a field in a class created with define-objc-class.

> syntax (set-ivar! obj-expr field-id value-expr)

Sets the Racket value of a field in a class created with define-objc-class.

> syntax (selector method-id)

Returns a selector (of FFI type _SEL) for the string form of method-id.

Example:

> > (tellv button setAction: #:type _SEL (selector terminate:))

> procedure (objc-is-a? obj cls) → boolean?
> obj : _id
> cls : _Class

Check whether obj is an instance of the Objective-C class cls or a subclass.

Changed in version 6.1.0.5 of package base: Recognize subclasses, instead of requiring an exact class match.

> procedure (objc-subclass? subcls cls) → boolean?
> subcls : _Class
> cls : _Class

Check whether subcls is cls or a subclass.

Added in version 6.1.0.5 of package base.

> procedure (objc-get-class obj) → _Class
> obj : _id

Extract the class of obj.

Added in version 6.3 of package base.

> procedure (objc-set-class! obj cls) → void?
> obj : _id
> cls : _Class

Changes the class of obj to cls. The object’s existing representation must be compatible with the new class.

Added in version 6.3 of package base.

> procedure (objc-get-superclass cls) → _Class
> cls : _Class

Returns the superclass of cls.

Added in version 6.3 of package base.

> procedure (objc-class-has-instance-method? cls sel) → boolean?
> cls : _Class
> sel : _SEL

Reports report cls offers an instance method sel.

Added in version 9.0.0.6 of package base.

> procedure (objc-dispose-class cls) → void?
> cls : _Class

Destroys cls, which must have no existing instances or subclasses.

Added in version 6.3 of package base.

> procedure (objc-block function-type? proc #:keep keep) → cpointer?
> function-type? : ctype
> proc : procedure?
> keep : (box/c list?)

Wraps a Racket function proc as an Objective-C block. The procedure must accept an initial pointer argument that is the “self” argument for the block, and that extra argument must be included in the given function-type.

Extra records that are allocated to implement the block are added to the list in keep, which might also be included in function-type through a #:keep option to _fun. The pointers registered in keep must be retained as long as the block remains in use.

Added in version 6.3 of package base.

> procedure (objc-block-function-pointer block) → fpointer?
> block : cpointer?

Extracts the function pointer of an Objective-C block. Cast this function pointer to a suitable function type to call it, where the block itself must be passed as the first argument to the function.

Added in version 8.13.0.1 of package base.

> syntax (with-blocking-tell form ...+)

Causes any tell, tellv, or super-tell expression syntactically within the forms to be blocking in the sense of the #:blocking? argument to _cprocedure. Otherwise, (with-blocking-tell form ...+) is equivalent to (let () form ...+).

Added in version 7.0.0.19 of package base.

#### 5.16.3 Raw Runtime Functions🔗ℹ

> procedure (objc_lookUpClass s) → (or/c _Class #f)
> s : string?

Finds a registered class by name.

> procedure (objc_getProtocol s) → (or/c _Protocol #f)
> s : string?

Finds a registered protocol by name.

> procedure (sel_registerName s) → _SEL
> s : string?

Interns a selector given its name in string form.

> procedure (objc_allocateClassPair cls s extra) → _Class
> cls : _Class
> s : string?
> extra : integer?

Allocates a new Objective-C class.

> procedure (objc_registerClassPair cls) → void?
> cls : _Class

Registers an Objective-C class.

> procedure (object_getClass obj) → _Class
> obj : _id

Returns the class of an object (or the meta-class of a class).

> procedure (class_getSuperclass cls) → _Class
> cls : _Class

Returns the superclass of cls or #f if cls has no superclass.

Added in version 6.1.0.5 of package base.

> > procedure
> > (class_addMethod |  | cls |  |  |  |
> > |  | sel |  |  |  |
> > |  | imp |  |  |  |
> > |  | type |  |  |  |
> > |  | type-encoding) |  | → |  | boolean?
> cls : _Class
> sel : _SEL
> imp : procedure?
> type : ctype?
> type-encoding : string?

Adds a method to a class. The type argument must be a FFI C type (see Type Constructors) that matches both imp and the not Objective-C type string type-encoding.

> > procedure
> > (class_addIvar |  | cls |  |  |  |
> > |  | name |  |  |  |
> > |  | size |  |  |  |
> > |  | log-alignment |  |  |  |
> > |  | type-encoding) |  | → |  | boolean?
> cls : _Class
> name : string?
> size : exact-nonnegative-integer?
> log-alignment : exact-nonnegative-integer?
> type-encoding : string?

Adds an instance variable to an Objective-C class.

> > procedure
> > (object_getInstanceVariable obj name) |  | → |  |
> > _Ivar |  | any/c
> obj : _id
> name : string?

Gets the value of an instance variable whose type is _pointer.

> procedure (object_setInstanceVariable obj name val) → _Ivar
> obj : _id
> name : string?
> val : any/c

Sets the value of an instance variable whose type is _pointer.

> value _Ivar : ctype?

The type of an Objective-C instance variable, an opaque pointer.

> procedure ((objc_msgSend/typed types) obj sel arg) → any/c
> types : (vector/c result-ctype arg-ctype ...)
> obj : _id
> sel : _SEL
> arg : any/c

Calls the Objective-C method on _id named by sel. The types vector must contain one more than the number of supplied args; the first FFI C type in type is used as the result type.

> > procedure
> > ((objc_msgSendSuper/typed |  | types) |  |  |  |
> > super |  |  |  |
> > sel |  |  |  |
> > arg) |  | → |  | any/c
> types : (vector/c result-ctype arg-ctype ...)
> super : _objc_super
> sel : _SEL
> arg : any/c

Like objc_msgSend/typed, but for a super call.

> procedure (make-objc_super id super) → _objc_super
> id : _id
> super : _Class
> value _objc_super : ctype?

Constructor and FFI C type use for super calls.

> > procedure
> > ((objc_msgSend/typed/blocking |  | types) |  |  |  |
> > obj |  |  |  |
> > sel |  |  |  |
> > arg) |  | → |  | any/c
> types : (vector/c result-ctype arg-ctype ...)
> obj : _id
> sel : _SEL
> arg : any/c
> > procedure
> > ((objc_msgSendSuper/typed/blocking |  | types) |  |  |  |
> > super |  |  |  |
> > sel |  |  |  |
> > arg) |  | → |  | any/c
> types : (vector/c result-ctype arg-ctype ...)
> super : _objc_super
> sel : _SEL
> arg : any/c

The same as objc_msgSend/typed and objc_msgSendSuper/typed, but specifying that the send should be blocking in the sense of the #:blocking? argument to _cprocedure.

Added in version 7.0.0.19 of package base.

#### 5.16.4 Legacy Library🔗ℹ

(require ffi/objc) | package: base

The ffi/objc library is a deprecated entry point to ffi/unsafe/objc. It exports only safe operations directly, and unsafe operations are imported using objc-unsafe!, analogous to scheme/foreign.

> syntax (objc-unsafe!)

Makes unsafe bindings of ffi/unsafe/objc available in the importing module.
top contents ← prev up next →