首页 > 解决方案 > Swift 构建错误“在范围内找不到‘C++ 字节数组’”

问题描述

Xcode build 无法识别 C++ .cpp 文件中定义的字节数组 sensor_data_bytes。

但它确实可以识别在相同文件中定义的 char 变量,并且还可以识别无符号 sensor_data_bytes。

func peripheral() 接收它需要复制到 C++ char 数组 sensor_data_bytes 的 BLE 通知数据。

结构体

我的工作区 Objective-C 应用程序项目“ sim_backend_UI ”导入了两个静态库项目(A 和 B)。

A) ' mobile_sensor_API ' 包含:

mobile_BLE_central.swift  
mobile_sensor_API.h  
mobile_sensor_API.mm  
mobile_sensor_API-Bridging-Header.h

B) ' mobile_hub ' 包含:

sdp_BLE.hpp  
sdp.cpp 

代码

// sdp_BLE.hpp, C++ in ObjC mobile_hub project
    
#ifndef BLE_bridge_h
#define BLE_bridge_h
    
//  Hublib receive of antenna data from sensor BLE:
#define SENSOR_DATA_BYTES 300
extern int BLE_packet_ready;
extern int BLE_packet_overruns;
extern char sensor_data_buf[];
extern unsigned sensor_data_bytes;

#endif //BLE_bridge_h
// sdp.cpp in ObjC mobile_hub project

#include "sdp.hpp"
#include "sdp_BLE.hpp"
    
//  Controls for receive of antenna data from Swift BLE notification data:
int BLE_packet_ready = 0;
int BLE_packet_overruns = 0;
char sensor_data_buf[ SENSOR_DATA_BYTES ];
unsigned sensor_data_bytes = 0;
. . .
    
//  Copies the data from func peripheral(...didUpdateValueFor...) to pucBuf.
int sdpRead(SDP_Handle ftHandle, UCHAR *pucBuf, ULONG ulBufferSize, ULONG *pulBytesTransferred, DWORD dwTimeOutInMs = 1000)
{
    int rv = 0;
    // Await sensor antenna data packet:
    // Poll buffer ready flag:
    for(;;)
    {
        // Buffer flag?
        if( BLE_packet_ready > 0 )
        {
            // Copy from BLE buf to hublib buffer:
            memcpy( pucBuf, sensor_data_buf, sensor_data_bytes );
            *pulBytesTransferred = sensor_data_bytes;
            // Lower flag:
            BLE_packet_ready = 0;
            // return
            break;                        
        }
        std::this_thread::yield();
        continue;
    }
    return rv;
}
// mobile_sensor_API-Bridging-Header.h
//  Bridging header from ObjC project that contains C++ to same ObjC project's .swift
//  Use this file to import your target's public headers that you would like to expose to Swift.

//#import "sdp_BLE.hpp"
    #define SENSOR_DATA_BYTES 300
    extern int BLE_packet_ready ;
    extern int BLE_packet_overruns ;
    extern  char sensor_data_buf[];
    extern  unsigned sensor_data_bytes ;

// mobile_sensor_API.h
//  ObjC static lib project: mobile_sensor_API
//  Contains .mm and .swift files
    
#import <Foundation/Foundation.h>
    
@interface Mobile_Sensor_API : NSObject
    
//  Swift interface to data-plane within mobile_hub objC static lib project:
extern "C++"  int BLE_packet_ready;
extern "C++"  int BLE_packet_overruns;
extern "C++"  char sensor_data_buf[];
extern "C++"  unsigned sensor_data_bytes;
// mobile_BLE_central.swift
//   ObjC static lib project: mobile_sensor_API
        
import UIKit
import CoreBluetooth
import os
    
@objc open
class BLE_Central: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate
{
    . . .

    /* Antenna Data packet received from sensor
     * This callback lets us know more data has arrived via notification on the characteristic */
    public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) 
    {
        // Buf flag still up?
        if( BLE_packet_ready > 0 )
        {
            // Count overruns:
            BLE_packet_overruns += 1;
        }
        else // else, Buf flag down?
        {
            sensor_data_bytes = UInt32(characteristic.value!.count);
            let characteristicData = characteristic.value

// TODO: build error "Cannot find 'sensor_data_buf' in scope" here
            characteristicData.copyBytes( to: sensor_data_buf, count: sensor_data_bytes );
// 
            // Raise buffer flag:
            BLE_packet_ready = 1;
        }
    }

    . . .
}

标签: c++objective-cswiftxcodecore-bluetooth

解决方案


问题是我的 ObjC 静态库项目中的 Swift 不直接与 C++ 交互。

解决方案:在 ObjC 静态库中为使用 C++ 访问 ObjC 静态库的 Swift 创建 .m 和 .h 包装器。包装器本质上是 Swift 调用的一个函数,它在 C++ 数据结构和 ObjC 静态库的数据结构之间架起一座桥梁,Swift 可以使用它。

将“C”接口的接口放入 Swift 的 ...-Bridging-Header.h 中。但是没有 C++ !将 C++ 接口(即 extern "C++" ...)放入 .h


推荐阅读