I'm wrapping a C++ API for the RPLIDAR SDK, for use by Swift. I've got an Objective-C++ class wrapping their C++ class, and I'd like to find the fastest (i.e. fewest copies) way of making the following call in Swift:
var measurements = [RPLidarMeasurement](repeating: RPLidarMeasurement(), count: 8192)
measurements.reserveCapacity(8192)
try! lidar.grabScanData(&measurements)
The wrapper method should be semantically equivalent to this, but I don’t know how to massage the types to make Swift happy, with the least amount of massaging:
- (BOOL)
grabScanData: (NSMutableData*) ioData error: (NSError**) outError
{
uint32_t nodeCount = 8192;
if (ioData.length < nodeCount)
{
// Set outError
return false;
}
u_result result = self.driver->grabScanData((rplidar_response_measurement_node_t*) ioData.bytes, nodeCount);
if IS_FAIL(result)
{
// Set outError
return false;
}
return true;
}
RPLidarMeasurement
looks like this, defined in the Objective-C(++) wrapper header (there's no C++ in the header):
typedef struct RPLidarMeasurement {
uint8_t sync_quality; // syncbit:1;syncbit_inverse:1;quality:6;
uint16_t angle_q6_checkbit; // check_bit:1;angle_q6:15;
uint16_t distance_q2;
} __attribute__((packed)) RPLidarMeasurement;
Importantly, I want to pass the size of array (the number of elements) to the call to grabScanData
. It's defined as:
u_result grabScanDataHq(RPLidarMeasurement * nodebuffer, size_t & count, uint32_t timeout = DEFAULT_TIMEOUT);
I don’t mind having a bunch of pointer manipulation, but I'd like to hide it from the Swift clients, and avoid copying, if possible.
Update: As I continue to work with this, I think the only thing I can do is create a class collection type for the measurement data, because I want it referenced all over the place and it's hard to ensure Swift doesn't copy the Array type.