Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C style unsigned char array and bitwise operators in Swift

I'm working on changing some Objective-C Code over to Swift, and I cannot figure out for the life of me how to take care of unsigned char arrays and bitwise operations in this specific instance of code.

Specifically, I'm working on converting the following Objective-C code (which deals with CoreBluetooth) to Swift:

unsigned char advertisementBytes[21] = {0};
[self.proximityUUID getUUIDBytes:(unsigned char *)&advertisementBytes];
advertisementBytes[16] = (unsigned char)(self.major >> 8);
advertisementBytes[17] = (unsigned char)(self.major & 255);

I've tried the following in Swift:

var advertisementBytes: CMutablePointer<CUnsignedChar>
self.proximityUUID.getUUIDBytes(advertisementBytes)
advertisementBytes[16] = (CUnsignedChar)(self.major >> 8)

The problems I'm running into are that getUUIDBytes in Swift seems to only take a CMutablePointer<CUnsignedChar> object as an argument, rather than an array of CUnsignedChars, so I have no idea how to do the later bitwise operations on advertisementBytes, as it seems it would need to be an unsignedChar array to do so.

Additionally, CMutablePointer<CUnsignedChar[21]> throws an error saying that fixed length arrays are not supported in CMutablePointers in Swift.

Could anyone please advise on potential work-arounds or solutions? Many thanks.

like image 709
Will Jack Avatar asked Jun 04 '14 23:06

Will Jack


1 Answers

Have a look at Interacting with C APIs

Mostly this

C Mutable Pointers

When a function is declared as taking a CMutablePointer argument, it can accept any of the following:

  • nil, which is passed as a null pointer
  • A CMutablePointer value
  • An in-out expression whose operand is a stored lvalue of type Type, which is passed as the address of the lvalue
  • An in-out Type[] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call

If you have declared a function like this one:

SWIFT

func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ } You

can call it in any of the following ways:

SWIFT

var x: Float = 0.0 
var p: CMutablePointer<Float> = nil 
var a: Float[] = [1.0, 2.0, 3.0] 
takesAMutablePointer(nil) 
takesAMutablePointer(p) 
takesAMutablePointer(&x) 
takesAMutablePointer(&a)

So you code becomes

var advertisementBytes = CUnsignedChar[]()
self.proximityUUID.getUUIDBytes(&advertisementBytes)
advertisementBytes[16] = CUnsignedChar(self.major >> 8)
like image 67
Rod Avatar answered Nov 15 '22 04:11

Rod