问题描述
有没有办法来编译本地C或C ++ code和暴露于斯威夫特在Linux上?我可以看到一些苹果电脑公司的库如都写在纯C,并且您可以访问他们只是雨燕通过导入。
要树立的榜样,让我们说,我有两个文件 Car.c
和 Car.h
定义结构名为车
。有没有办法,我可以编译并通过编写import语句使用它们斯威夫特的方式?
进口车
我试着写 module.modulemap
目录里面的文件,其中 .C
, .H
和 Package.swift
文件位于:
模块租车{
头Car.h
出口 *
}
和运行迅速构建
。这种屈服错误:
<&不明GT; 0:错误:意外'命令'值(预期图)
<&不明GT; 0:错误:无法加载生成文件
我使用的雨燕3.0-dev的(2016年3月24日) P>
[更新1]
我已经联系MAX(mxcl) - 斯威夫特包管理器的创始人之一,他告诉我摆脱了 modulemap
,把 .C
和 .H
直接在来源
文件夹中。我做了之后包编译但它不是作为模块。我也不能调用任何在 .H
文件中定义的功能。
如果你建立一个库出你的C code,你可以创建一个的系统模块的吧,然后可以被导入到斯威夫特,看到这样的回答:
要处理这个任务的另一种方法是创建一个桥接报头,通过@Philip的建议。下面是一个过于简单的例子。让我们考虑下面的C code:
/ *在car.h * /
INT调用getInt();/ *在car.c * /
诠释调用getInt(){返回123; }
我们将使用car.h作为桥接报头。雨燕源(在文件 junk.swift
)
打印(你好,从快捷!)
VAR I =调用getInt()
打印(这里是从C的int:\\(I))
首先,创建一个目标文件, car.o
,从 car.c
:
GCC -c car.c
现在建立一个可执行文件,垃圾
,如下:
swiftc -import-objc头car.h junk.swift car.o -o垃圾
运行可执行给出:
$ ./junk
你好,从快捷!
这里是从C的int:123!
的 -import-objc头
选项是隐藏的。看到它和一堆其他隐藏的选项,运行:
swiftc -help隐藏
我做的Ubuntu 14.04这个使用SWIFT 3.0开发快照从4月12日,可在这里: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 ++中,你需要创建一个包装,使用的externC写的C ++源文件并用C ++编译器编译,但是从C可调用的函数
。这些函数然后可以从夫特称为任何C函数。见,例如,这样的回答:Can我用C ++混合斯威夫特?像Objective - C的.mm文件
Is there a way to compile native C or C++ code and expose it to Swift on Linux? I can see that several Apple libraries like libdispatch are written in pure C and that you can access them in Swift just by importing them.
To set the example let's say that I have two files Car.c
and Car.h
that define structure named Car
. Is there a way that I can compile them and use them in Swift by writing import statement?
import Car
I've tried writing module.modulemap
file inside directory where .c
, .h
and Package.swift
files are located:
module Car {
header "Car.h"
export *
}
and running swift build
. This yield error:
<unknown>:0: error: unexpected 'commands' value (expected map)
<unknown>:0: error: unable to load build file
I'm using Swift version 3.0-dev (March 24 2016)
[Update 1]
I've contacted Max(mxcl) - one of the creators of Swift Package Manager and he told me to get rid of the the modulemap
and put the .c
and .h
files directly in Sources
folder. After I did that package compiled but it's not available as module. Also I can't call any of the defined functions in the .h
file.
If you build a library out of your C code, you can create a system module for it, which can then be imported into Swift, see this answer: Use a C library in Swift on Linux.
Another way to approach this task is to create a bridging header, as suggested by @Philip. Here is an oversimplified example. Let's consider the following C code:
/* In car.h */
int getInt();
/* In car.c */
int getInt() { return 123; }
We will use car.h as the bridging header. The swift source is (in file junk.swift
):
print("Hi from swift!")
var i = getInt()
print("And here is an int from C: \(i)!")
First, create an object file, car.o
, from car.c
:
gcc -c car.c
Now build an executable, junk
, as follows:
swiftc -import-objc-header car.h junk.swift car.o -o junk
Running the executable gives:
$ ./junk
Hi from swift!
And here is an int from C: 123!
The -import-objc-header
option is hidden. To see it and a bunch of other hidden options, run:
swiftc -help-hidden
I did this using Swift 3.0 development snapshot for Ubuntu 14.04 from April 12, available here: https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a/swift-DEVELOPMENT-SNAPSHOT-2016-04-12-a-ubuntu14.04.tar.gz
Now, if you want to use C++, you will need to create a wrapper, written in a C++ source file and compiled with a C++ compiler, but with functions callable from C by using extern "C"
. Those functions can then be called from Swift as any C function. See, for example, this answer: Can I mix Swift with C++? Like the Objective - C .mm files
这篇关于编译C code和Linux下暴露于斯威夫特的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!