问题:在Linux下编译C代码并暴露给Swift

有没有办法在 Linux 上编译原生 C 或 C++ 代码并将其公开给 Swift?我可以看到像libdispatch这样的几个 Apple 库是用纯 C 编写的,您只需导入它们就可以在 Swift 中访问它们。

举例来说,假设我有两个文件Car.cCar.h,它们定义了名为Car的结构。有没有一种方法可以编译它们并通过编写 import 语句在 Swift 中使用它们?

import Car

我尝试在.c.hPackage.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 文件

Logo

更多推荐