我想用C写一个模块,用C写一些在Swift中可以访问的函数。
我有点困惑,因为无论我做什么,SPM坚持试图编译C代码,就好像它是Objective-C一样,当然它找不到正确的头。
这是我的尝试。
源目录结构:
Sources
|
+-CxxModule
| |
| +-include
| | |
| | +-CxxModule.hpp
| |
| +-CxxModule.cpp
|
+-SwiftModule
|
+-SwiftModule.swift
清单Package.swift
如下:
// swift-tools-version: 5.6
import PackageDescription
let package = Package(
name: "CxxLibrary",
products: [
.library(
name: "CxxLibrary",
targets: ["SwiftModule"]),
],
dependencies: [
],
targets: [
.target(
name: "CxxModule",
dependencies: []),
.target(
name: "SwiftModule",
dependencies: ["CxxModule"],
path: "Sources/SwiftModule"
),
]
)
CxxModule.hpp
如下:
#ifndef CxxModule_hpp
#define CxxModule_hpp
#include <iostream>
extern "C" void printHello();
#endif /* CxxModule_hpp */
CxxModule.cpp
如下:
#include "CxxModule.hpp"
void printHello() {
// use something from the standard library to make sure
// c++ is really being used
std::cout << "Hello, world!" << std::endl;
}
最后,SwiftModule.swift
:
import CxxModule
我错过了什么?有没有办法告诉SPM这个模块应该是C的?或者这只是目前不受支持?
注意:如果我删除Swift目标,C编译得很好。
2条答案
按热度按时间jqjz2hbq1#
我能够解决这个问题。答案是“是的”,只要暴露给Swift的头在纯C中可读。
首先,我将所有特定于C++的代码(特别是引用标准库的头文件)移到源
cpp
文件中:其次,我添加了宏,使标题在C和C++中都可读:
文件结构和Swift模块保持不变。
教训:任何将被C和Swift读取的头部必须两者都可读。(Swift能够理解C头文件,但不能理解C头文件,至少在目前的状态下是这样。
brccelvz2#
对于其他在C和Swift中挣扎的人来说,有几个注意事项(对于C来说,“简单地”是一个命名的问题。我确实知道,但是如果没有一个正常运行的C代码,C是不可能完成使命。
回顾一下:
1.假设您有“C”代码,让我们称之为libC(一个文件夹),它包含 *.c和 *.h文件。
1.如果要构建一个 Package 器,可以说libCWrapper
1.在Xcode中构建一个名为libCWrapper的包
1.现在第一个技巧:我们需要两个目标和两个产品。因此,补充:
**注意:**swift libCWrapper依赖于libC。
1.我们还必须添加/更改“C源代码:
所有的“C”代码必须进入一个饲料名称为“C”目标,但包括一个级别。所以:
Sources ->[libC] sampleCall.c [include] -> [sampleCall.h]
所以:
平台:[ .macOS(.v10_12),.iOS(.v9)],
1.内部测试:
@testable import libCWrapper**@testable import libC**
添加C产品。所以测试可以是:
在C中,我们有:
现在,你可以在测试中从Swift调用C,这只是一个“open”/“public”和类似的问题。