使用C库导入Swift模块

时间:2015-12-22 17:18:23

标签: c linux swift curses

我已按照this page的说明编写了Curses包装器模块。

但是,我不知道如何在使用它的模块中正常工作。

我有3个并行目录:CCurses,CursesWrapper,ModuleUsingCursesWrapper。

CCurses包含一个空的Package.swift文件和一个包含

的module.modulemap文件
module CCurses [system] {
    header "/usr/include/curses.h"
    link "curses"
    export *
}

CursesWrapper包含一个包含。

的Package.swift文件
import PackageDescription

let package = Package(dependencies: [.Package(url: "../CCurses", majorVersion: 1)])

和包含

的general.swift文件
import CCurses

public func startCurses() -> Void{
    initscr()}

public func getchar() -> Void{
    getch()}

public func endCurses() -> Void{
    endwin()}

ModuleUsingCursesWrapper包含一个包含

的Package.swift文件
import PackageDescription

let package = dependencies: [.Package(url: "../CursesWrapper", majorVersion: 1)])

和包含

的main.swift文件
import CursesWrapper

startCurses()
getchar()
endCurses()

在ModuleUsingCursesWrapper中运行swift build时,我得到以下输出:

Cloning Packages/CursesWrapper
Cloning Packages/CCurses
Compiling Swift Module 'CursesWrapper' (1 sources)
Linking Library:  .build/debug/CursesWrapper.a
Compiling Swift Module 'ModuleUsingCursesWrapper' (1 sources)
Linking Executable:  .build/debug/ModuleUsingCursesWrapper
.../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF14CursesWrapper11startCursesFT_T_':
.../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:5: undefined reference to `initscr'
.../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF1CursesWrapper7getcharFT_T_':
.../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:8: undefined reference to `getch'
.../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF14CursesWrapper9endCursesFT_T_':
.../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:11: undefined reference to `endwin'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
< unknown >:0: error: link command failed with exit code 1 (use -v to see invocation)
< unknown :0: error: build had 1 command failures
swift-build: exit(1): [".../Swift/usr/bin/swift-build-tool", "-f", ".../ModuleUsingCursesWrapper/.build/debug/ModuleUsingCursesWrapper.o/llbuild.yaml"]

似乎在编译ModuleUsingCursesWrapper时,找不到curses函数。我该如何解决这个问题?

(我在Linux上)

1 个答案:

答案 0 :(得分:0)

在Ubuntu 14.04盒子上玩了一段时间之后,我遇到了同样的错误。经过一些额外的实验,我能够通过将以下内容添加到main.swift

来解决它
import CCurses

使用包装器的模块的Package.swift文件仅引用CursesWrapper,但如果CCurses未导入main.swift,则会发生未定义的引用错误。

从您提供的swift.org链接可以看到导入模块的依赖关系的需求,其中讨论了JasPer / JPEG示例。严格来说,JasPer不是JPEG的包装器,而只是另一个系统模块,但想法是一样的:如果我们导入依赖于模块B的模块A,那么我们也应该导入模块B.

BTW我必须将public func getchar()更改为public func getChar()并相应地修改main.swift。否则,在编译ambiguous use of 'getchar()'时,我会收到main.swift错误。显然它已经在CCurses中定义,这并不奇怪,因为它是一个标准的C函数。