Sai*_*ira 11 c linux swift swift2
有没有办法编译本机C或C++代码并将其暴露给Linux上的Swift?我可以看到像libdispatch这样的几个Apple库是用纯C编写的,只要导入它们就可以在Swift中访问它们.
要设置示例,假设我有两个文件Car.c并Car.h定义了名为的结构Car.有没有办法可以编译它们并通过编写import语句在Swift中使用它们?
import Car
Run Code Online (Sandbox Code Playgroud)
我试着写module.modulemap里面目录下的文件.c,.h并且Package.swift文件位于:
module Car {
header "Car.h"
export *
}
Run Code Online (Sandbox Code Playgroud)
并运行swift build.这个产量误差:
<unknown>:0: error: unexpected 'commands' value (expected map)
<unknown>:0: error: unable to load build file
Run Code Online (Sandbox Code Playgroud)
我正在使用Swift 3.0-dev版本(2016年3月24日)
[更新1]
我已经联系了Max(mxcl) - Swift Package Manager的创建者之一,他告诉我要删除modulemap它.c并将.h文件直接放在Sources文件夹中.我编译完这个包后,但它不能用作模块.此外,我无法调用文件中的任何已定义函数.h.
Ana*_*i P 15
如果你用你的C代码构建一个库,你可以为它创建一个系统模块,然后可以将其导入到Swift中,请参阅以下答案:在Linux上使用Swift中的C库.
处理此任务的另一种方法是创建桥接头,如@Philip所建议的那样.这是一个简单的例子.让我们考虑以下C代码:
/* In car.h */
int getInt();
/* In car.c */
int getInt() { return 123; }
Run Code Online (Sandbox Code Playgroud)
我们将使用car.h作为桥接头.swift源是(在文件中junk.swift):
print("Hi from swift!")
var i = getInt()
print("And here is an int from C: \(i)!")
Run Code Online (Sandbox Code Playgroud)
首先car.o,从car.c以下位置创建一个目标文件:
gcc -c car.c
Run Code Online (Sandbox Code Playgroud)
现在构建一个可执行文件,junk如下所示:
swiftc -import-objc-header car.h junk.swift car.o -o junk
Run Code Online (Sandbox Code Playgroud)
运行可执行文件给出:
$ ./junk
Hi from swift!
And here is an int from C: 123!
Run Code Online (Sandbox Code Playgroud)
该-import-objc-header选项已隐藏.要查看它和一堆其他隐藏选项,请运行:
swiftc -help-hidden
Run Code Online (Sandbox Code Playgroud)
我从4月12日开始使用Ubuntu 14.04的Swift 3.0开发快照,可以在这里找到:https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a/swift-DEVELOPMENT-快照2016年4月12日-A-ubuntu14.04.tar.gz
现在,如果你想使用C++,你需要创建一个包装器,用C++源文件编写并用C++编译器编译,但是使用C语言可以调用的函数extern "C".然后可以从Swift中调用这些函数作为任何C函数.例如,请参阅以下答案:我可以将Swift与C++混合使用吗?像Objective - C .mm文件一样
快速使用C函数需要一个桥接标头,其中包含您需要的所有C功能。例如,myBridgingHeader.h包含#include“ Car.h”以及您想要的任何其他C东西。我认为目前不支持C ++。
一旦有了桥接头,就需要迅速意识到这一点。Xcode用户将其添加到项目中后即可免费获得。在Linux中,编译时使用'-import-objc-header / path / to / header'标志。
编辑:我在下面添加了一个完整的示例,其中包含6个文件,用于可能有此问题的其他任何人。它基本上与上面的相同,但是直到我把它放在一起之前,我一直没有看到。同样,它对于需要链接静态库的人可能很有用。
将下面的文件内容复制到适当命名的文件make,然后./hello就可以了。作为记录,我仅在swift 2.2-dev版本上运行(用于swift --version检查您的版本)
hello.swift:
let n: Int32 = 5
print("Hello, Swift World!")
print("mult2(\(n,N)) = \(mult2(n,N))")
print("CONST1=\(CONST1), CONST2=\(CONST2), CONST3=\(CONST3)")
Run Code Online (Sandbox Code Playgroud)bridge.h:
#include "defs.h"
#include "mult.h"
Run Code Online (Sandbox Code Playgroud)defs.h:
#define CONST1 1
#define CONST2 2
#define CONST3 3
Run Code Online (Sandbox Code Playgroud)mult.h:
#define N 7
int mult2(int,int);
Run Code Online (Sandbox Code Playgroud)mult.c:
#include "defs.h"
#include "mult.h"
int mult2(int a, int b)
{
return a*b;
}
Run Code Online (Sandbox Code Playgroud)生成文件:
all: hello
hello: libmult.a
swiftc hello.swift -import-objc-header ./bridge.h -L. -lmult -o hello
libmult.a: mult.o
ar -rc libmult.a mult.o
ranlib libmult.a
mult.o: mult.c mult.h defs.h
gcc -c mult.c -o mult.o
.PHONY: clean
clean:
rm -f *.o *.a hello
Run Code Online (Sandbox Code Playgroud)