typedef struct from C to Swift

1.8k Views Asked by At

I'm working on a Swift app that accesses a C library.

The .h file contains a typedef struct:

typedef struct _DATA_KEY_ * CURRENT_DATA_KEY;

And there a method in another class:

 -(int) initWithKey(CURRENT_DATA_KEY * key);

I need to create a CURRENT_DATA_KEY in my code. Not sure how I can achieve that in Swift.

There is some old Objective-C code that uses:

CURRENT_DATA_KEY key = NULL;
initWithKey(key)

I've tried:

let myKey = UnsafeMutablePointer<CURRENT_DATA_KEY>.allocate(capacity: 1)

But when I try to use it later as an argument in the function, I get the error:

Cannot convert value of type 'UnsafeMutablePointer<_DATA_KEY_>' (aka 'UnsafeMutablePointer(<OpaquePointer>)') to expected argument type 'UnsafeMutablePointer(<_DATA_KEY_?>!)'

Which looks like the function is expecting an optional value?

I also tried:

let myKey: CURRENT_DATA_KEY? = nil
let myKey: CURRENT_DATA_KEY = NSNull()

But those get similar type errors.

How do I create: UnsafeMutablePointer(<_DATA_KEY_?>!)

1

There are 1 best solutions below

0
On

It's been a bit since I've done this but IIRC this:

typedef struct _DATA_KEY_ * CURRENT_DATA_KEY;
-(int) initWithKey(CURRENT_DATA_KEY * key);

Is actually equivalent to:

-(int) initWithKey(struct _DATA_KEY_ ** key);

So if we look up Interacting with C APIs: Pointers it falls under:

Type **

Which becomes:

AutoreleasingUnsafeMutablePointer<Type>

If you know the members of the C struct then you may be able to treat it like a Swift struct and use the synthesized init method. So if it is defined like this:

struct _DATA_KEY_ { 
  int foo
};

It becomes like this in Swift:

public struct _DATA_KEY_ { 
  var foo: Int
  init()
  init(foo: Int)
}

And you call the init method like:

// no parameter
let myKey = AutoreleasingUnsafeMutablePointer<_DATA_KEY_>(&_DATA_KEY_())

// parameter
let myKey = AutoreleasingUnsafeMutablePointer<_DATA_KEY_>(&_DATA_KEY_(foo: 12))

I have not tried this code but I've followed the advice in the Apple document before and it's worked out well.