Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - C API bridge - how to handle null pointers

In Swift I am using C API that returns struct with char array (containing UTF8 null terminated string or null).

struct TextStruct {
   char * text;
   //other data
}

I use:

let text: String = String(cString: data.text)

This works, however, when data.text is nullptr, this fails with

fatal error: unexpectedly found nil while unwrapping an Optional value

Is there any workaround, or I have to check data.text manually before using cString ctor?

like image 957
Martin Perry Avatar asked Jan 04 '23 04:01

Martin Perry


1 Answers

In addition to Gwendal Roué's solution: You can annotate the C API to indicate whether the pointer can be null or not. For example,

struct TextStruct {
    char * _Nullable text;
    //other data
};

is imported to Swift as

public struct TextStruct {
    public var text: UnsafeMutablePointer<Int8>?
    // ...
}

where var text is a "strong" optional instead of an implicitly unwrapped optional. Then

let text = String(cString: data.text)
// value of optional type 'UnsafeMutablePointer<Int8>?' not unwrapped; ...

no longer compiles, and forces you to use optional binding or other unwrapping techniques, and the "fatal error: unexpectedly found nil" cannot happen anymore accidentally.

For more information, see "Nullability and Objective-C" from the Swift Blog – despite the title, it can be used with pure C as well.

like image 130
Martin R Avatar answered Jan 14 '23 06:01

Martin R