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

如何将C++结构体转为兼容C约定的Swift类型?遇内存访问错误求解

问题描述

有一个位于动态库中的C++结构体定义如下:

typedef struct {
    int a;
} addingTemp;

对应的相加函数实现:

void add(addingTemp a, addingTemp b, addingTemp& c) {
    c.a = a.a + b.a;
}

该函数的导出声明为:

DLL_PUBLIC void add(
        addingTemp a,
        addingTemp b,
        addingTemp* c,);

尝试在Swift中调用该函数时,将addingTemp实现为继承NSObject的类:

public class addingTemp: NSObject {
    public var a : CInt
    init(a: CInt = 0) {
        self.a = a
    }
}

调用代码如下:

typealias add = @convention(c) (addingTemp, addingTemp, UnsafeMutablePointer<addingTemp>) -> Void

func addLib(a :  addingTemp, b:  addingTemp, out: inout addingTemp) -> Void{
    guard dylib != nil  else {
        errorDylib()
        return
    }
    guard let sym = dlsym(dylib, "add")  else {
        errorDylib()
        return
    }
    
    let f = unsafeBitCast(sym, to:add.self )
    
    let result : Void = f(a ,b, &out)
 //   closeDylib()
    return
}

运行时出现内存访问错误,推测是类型不匹配导致存储异常,请问如何在Swift中正确创建符合C兼容约定的结构体?

解决方案

问题核心是Swift中用了引用类型的NSObject子类,而C的结构体是值类型,两者内存布局完全不兼容,导致调用C函数时内存访问出错。正确的做法是在Swift中定义一个与C结构体内存布局一致的值类型结构体,不需要继承任何类。

正确的addingTemp Swift定义

public struct addingTemp {
    public var a: CInt
}

Swift的结构体默认使用与C兼容的内存布局(对于这种简单的平凡结构体),成员a的类型CInt对应C中的int,保证了内存结构完全匹配。

调整后的调用代码

只需将类型替换为上述结构体即可,核心逻辑无需修改:

typealias addFn = @convention(c) (addingTemp, addingTemp, UnsafeMutablePointer<addingTemp>) -> Void

func addLib(a: addingTemp, b: addingTemp, out: inout addingTemp) {
    guard let dylib = dylib else {
        errorDylib()
        return
    }
    guard let sym = dlsym(dylib, "add") else {
        errorDylib()
        return
    }
    
    let f = unsafeBitCast(sym, to: addFn.self)
    f(a, b, &out)
}

关键说明

  • C的结构体是值类型,内存中直接存储成员数据;Swift的NSObject子类是引用类型,内存中存储的是对象指针,两者内存布局完全不同,传递给C函数时会导致参数解析错误,触发内存访问异常。
  • 对于仅包含基本数据类型的简单结构体,Swift结构体默认遵循与C一致的内存布局规则,无需额外标记。

内容的提问来源于stack exchange,提问作者Ryan Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:30:49