在Linux下编译C代码并暴露给Swift
问题:在Linux下编译C代码并暴露给Swift
有没有办法在 Linux 上编译原生 C 或 C++ 代码并将其公开给 Swift?我可以看到像libdispatch这样的几个 Apple 库是用纯 C 编写的,您只需导入它们就可以在 Swift 中访问它们。
举例来说,假设我有两个文件Car.c
和Car.h
,它们定义了名为Car
的结构。有没有一种方法可以编译它们并通过编写 import 语句在 Swift 中使用它们?
import Car
我尝试在.c
、.h
和Package.swift
文件所在的目录中写入module.modulemap
文件:
module Car {
header "Car.h"
export *
}
并运行swift build
。这产生错误:
<unknown>:0: error: unexpected 'commands' value (expected map)
<unknown>:0: error: unable to load build file
我正在使用 Swift 3.0-dev 版本(2016 年 3 月 24 日)
[更新 1]
我联系了 Max(mxcl) - Swift Package Manager 的创建者之一,他告诉我摆脱modulemap
并将.c
和.h
文件直接放在Sources
文件夹中。在我编译了那个包但它不能作为模块使用之后。我也不能调用.h
文件中定义的任何函数。
解答
如果你用你的 C 代码构建一个库,你可以为它创建一个 system 模块,然后可以将其导入 Swift,请参阅这个答案:在 Linux 上使用 Swift 中的 C 库。
处理此任务的另一种方法是创建一个桥接头,正如@Philip 所建议的那样。这是一个过于简单的例子。让我们考虑以下 C 代码:
/* In car.h */
int getInt();
/* In car.c */
int getInt() { return 123; }
我们将使用 car.h 作为桥接头。快速来源是(在文件junk.swift
中):
print("Hi from swift!")
var i = getInt()
print("And here is an int from C: \(i)!")
首先,从car.c
创建一个目标文件car.o
:
gcc -c car.c
现在构建一个可执行文件junk
,如下所示:
swiftc -import-objc-header car.h junk.swift car.o -o junk
运行可执行文件给出:
$ ./junk
Hi from swift!
And here is an int from C: 123!
-import-objc-header
选项被隐藏。要查看它和许多其他隐藏选项,请运行:
swiftc -help-hidden
我从 4 月 12 日开始使用 Ubuntu 14.04 的 Swift 3.0 开发快照执行此操作,可在此处获得:https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a/swift-DEVELOPMENT -SNAPSHOT-2016-04-12-a-ubuntu14.04.tar.gz
现在,如果你想使用 C++,你需要创建一个包装器,用 C++ 源文件编写并用 C++ 编译器编译,但使用extern "C"
可以从 C 调用函数。然后可以从 Swift 调用这些函数作为任何 C 函数。例如,请参阅此答案:Can I mix Swift with C++?像 Objective - C .mm 文件
更多推荐
所有评论(0)