如何在静态库中整合Swift与C代码并仅暴露Swift接口
构建仅暴露Swift接口的Swift+C静态库完整步骤
需求说明
创建包含Swift和C代码的静态库,仅对外暴露Swift类Test,隐藏C函数testFromC()的实现与接口。
基础文件内容
Test.swift
class Test { func test() -> CInt { return testFromC() } }
Test.c
#include "Test.h" int testFromC(void) { return 0xdeadbeef; }
Test.h
int testFromC(void);
方案一:Xcode可视化构建(推荐)
1. 创建静态库项目
- 打开Xcode,选择
File > New > Project - 选择
Framework & Library分类下的Static Library,点击Next - 填写产品名称(如
SwiftCStaticLib),语言选择Swift,完成项目创建。
2. 导入C文件并配置可见性
- 将
Test.c和Test.h添加到项目中,确保它们的Target Membership仅勾选当前静态库目标。 - 进入项目目标的
Build Phases > Headers,将Test.h移至Project或Private分组,避免放入Public分组(防止外部获取)。
3. 创建私有模块映射文件
- 在项目中新建文件
module.modulemap,内容如下:
module SwiftCStaticLib_Private [private] { header "Test.h" export * }
- 确保该文件的Target Membership仅勾选当前静态库目标,且存放路径与C文件一致。
4. 配置Swift编译参数
- 进入项目目标的
Build Settings:- 搜索
Swift Compiler - Search Paths > Import Paths,添加模块映射文件所在目录(如$(SRCROOT)/SwiftCStaticLib,或直接填.表示当前目录)。 - 搜索
Allow Non-modular Includes in Framework Modules,设置为YES(兼容部分编译场景)。
- 搜索
5. 修改Swift文件导入私有模块
更新Test.swift,导入私有模块以访问C函数:
import SwiftCStaticLib_Private class Test { func test() -> CInt { return testFromC() } }
6. 编译并验证
- 选择模拟器/真机目标,点击
Build完成编译。 - 创建测试项目导入该静态库,编写代码验证:
import SwiftCStaticLib let test = Test() print(test.test()) // 输出3735928559(即0xdeadbeef的十进制值) // 尝试调用testFromC()会直接报错,说明C接口未对外暴露
方案二:命令行构建
1. 编译C代码为目标文件
clang -c Test.c -o Test.o
2. 创建私有模块映射文件
同Xcode方案的module.modulemap内容,放在与C文件同目录下。
3. 编译并生成静态库
swiftc -static -emit-library Test.swift Test.o -I . -module-name SwiftCStaticLib -o libSwiftCStaticLib.a
参数说明:
-I .:指定模块映射文件的搜索目录-module-name:设置Swift模块名称-static:生成静态库
4. 验证静态库
创建测试文件Main.swift:
import SwiftCStaticLib let t = Test() print(t.test())
编译并运行:
swiftc Main.swift -L . -lSwiftCStaticLib -o TestApp ./TestApp
运行后输出3735928559,尝试调用testFromC()会报错,符合预期。
内容的提问来源于stack exchange,提问作者Dag Ågren
相关产品推荐
相关产品推荐

