You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift调用std::vector触发EXC_BAD_ACCESS错误求助

解决Swift调用返回std::vector的Objective-C++方法时的EXC_BAD_ACCESS错误

问题根源

纯Objective-C头文件(.h)无法直接声明返回std::vector<int>的方法——Objective-C编译器不识别C类型,这会导致方法签名的ABI(应用二进制接口)不匹配,运行时调用时出现内存访问错误,即使实现文件是Objective-C(.mm)也无法修复头文件层面的类型声明问题。

解决方案

方案一:用NSArray中转(最简洁的兼容方式)

避免在Objective-C接口中直接暴露C++类型,改用Objective-C原生容器做中转:

修改头文件(.h)

@interface getVectorObject : NSObject
+ (NSArray<NSNumber *> *)getVectorAsArray;
@end

修改Objective-C++实现文件(.mm)

@implementation getVectorObject

+ (NSArray<NSNumber *> *)getVectorAsArray {
    std::vector<int> vec = {1,2,3};
    NSMutableArray *array = [NSMutableArray array];
    for (int num in vec) {
        [array addObject:@(num)];
    }
    return array;
}

@end

Swift调用代码

Button(action: {
    let objcArray = getVectorObject.getVectorAsArray()
    // 转换为Swift原生数组
    let swiftArray = objcArray.compactMap { $0 as? Int }
    print(swiftArray)
}, label: {
    Text("Button")
})

方案二:用不透明指针包装C容器(需直接操作C对象时)

通过void*封装std::vector,在Objective-C接口中暴露操作方法:

修改头文件(.h)

@interface getVectorObject : NSObject
+ (void *)getVectorOpaque;
+ (void)freeVectorOpaque:(void *)vector;
+ (int)vectorOpaqueGetElement:(void *)vector atIndex:(NSUInteger)index;
+ (NSUInteger)vectorOpaqueCount:(void *)vector;
@end

修改Objective-C++实现文件(.mm)

@implementation getVectorObject

+ (void *)getVectorOpaque {
    std::vector<int> *vec = new std::vector<int>{1,2,3};
    return vec;
}

+ (void)freeVectorOpaque:(void *)vector {
    delete static_cast<std::vector<int>*>(vector);
}

+ (int)vectorOpaqueGetElement:(void *)vector atIndex:(NSUInteger)index {
    std::vector<int> *vec = static_cast<std::vector<int>*>(vector);
    return index < vec->size() ? (*vec)[index] : -1;
}

+ (NSUInteger)vectorOpaqueCount:(void *)vector {
    std::vector<int> *vec = static_cast<std::vector<int>*>(vector);
    return vec->size();
}

@end

Swift调用代码

Button(action: {
    let vectorPtr = getVectorObject.getVectorOpaque()
    defer {
        // 确保释放C++对象,避免内存泄漏
        getVectorObject.freeVectorOpaque(vectorPtr)
    }
    let count = getVectorObject.vectorOpaqueCount(vectorPtr)
    for i in 0..<count {
        let num = getVectorObject.vectorOpaqueGetElement(vectorPtr, atIndex: i)
        print(num)
    }
}, label: {
    Text("Button")
})

方案三:直接使用Swift-C++互操作(跳过Objective-C中间层)

若项目支持直接Swift-C++互操作,可省去Objective-C桥接:

创建C++头文件(VectorUtils.hpp)

#include <vector>

std::vector<int> getVector();

创建C++实现文件(VectorUtils.cpp)

#include "VectorUtils.hpp"

std::vector<int> getVector() {
    return {1,2,3};
}

配置Xcode并编写Swift代码

  1. 在Target的Build Settings中,将Swift Compiler - Language下的C++ Interoperability设置为Enabled
  2. 将VectorUtils.hpp加入Swift桥接文件,或通过模块导入
  3. Swift调用代码:
Button(action: {
    let cppVector = getVector()
    for num in cppVector {
        print(num)
    }
}, label: {
    Text("Button")
})

内容的提问来源于stack exchange,提问作者Łukasz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:20:12