Swift から C の関数を呼び出す方法を Swift-NIO のコードを読みながら試した。

プロジェクトの構造は普通の2モジュールあるプロジェクト
.
├── Package.swift
├── Sources
│ ├── CExp
│ │ ├── include
│ │ │ └── c_exp.h
│ │ └── shim.c
│ └── SwiftClangCompat
│ └── main.swift
└── Tests
├── LinuxMain.swift
└── SwiftClangCompatTests
├── SwiftClangCompatTests.swift
└── XCTestManifests.swift
CExp は C 言語の関数を呼び出すモジュールで、次のような関数を定義している
c_exp.h
#ifndef C_EXP_H #define C_EXP_H #include <stdio.h> void POSIX_print(char *string); #endif
実装はただ単に printf を呼び出すだけ
shim.c
#include <c_exp.h> #include <stdio.h> void POSIX_print(char *string) { printf("%s\n", string); }
このモジュールを swift のモジュールが参照できるように、 Package.swift を調整する。
// swift-tools-version:4.2 import PackageDescription let package = Package( name: "SwiftClangCompat", dependencies: [], targets: [ .target(name: "CExp", dependencies: []), .target(name: "SwiftClangCompat", dependencies: ["CExp"]), .testTarget(name: "SwiftClangCompatTests", dependencies: ["SwiftClangCompat"]), ] )
そのうえで、Swift 側で C のモジュールを import して呼び出す。
import Foundation import CExp let string = "(☝՞ਊ ՞)☝ウェーイwww " string.withCString { (strPtr: UnsafePointer<Int8>) -> Void in POSIX_print(UnsafeMutablePointer(mutating: strPtr)) }
呼び出し結果
$ swift run SwiftClangCompat (☝՞ਊ ՞)☝ウェーイwww