diff --git a/swift-from-go/Package.swift b/swift-from-go/Package.swift new file mode 100644 index 0000000..9cd33be --- /dev/null +++ b/swift-from-go/Package.swift @@ -0,0 +1,29 @@ +// swift-tools-version:4.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "go-swift", + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "go_swift", + type: .dynamic, + targets: ["go-swift"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "go-swift", + dependencies: []), + .testTarget( + name: "go-swiftTests", + dependencies: ["go-swift"]), + ] +) \ No newline at end of file diff --git a/swift-from-go/README.md b/swift-from-go/README.md new file mode 100644 index 0000000..4ee913b --- /dev/null +++ b/swift-from-go/README.md @@ -0,0 +1,15 @@ +# go-swift + +> Clone from: https://github.com/onderweg/swift-from-go + +Example code, complementing the blog post: ["Calling Swift from Go"](https://dev.to/gerwert/calling-swift-from-go-5dbk) + +_Note: this repo is more than 3 years old. Feel free to use it as reference, but don't expect it to work with current versions of Go and Swift._ + +## Building & Running + +``` +$ swift build +$ go build -o hello +$ ./hello +``` diff --git a/swift-from-go/Sources/go-swift/go_swift.swift b/swift-from-go/Sources/go-swift/go_swift.swift new file mode 100644 index 0000000..8f835a0 --- /dev/null +++ b/swift-from-go/Sources/go-swift/go_swift.swift @@ -0,0 +1,7 @@ +@_cdecl("sayHello") // export to C as `sayHello`` +public func sayHello(namePtr: UnsafePointer?) { + // Creates a new string by copying the null-terminated UTF-8 data (C String) + // referenced by the given pointer. + let name = String(cString: namePtr!) + print("Welcome, \(name)!") +} diff --git a/swift-from-go/Tests/LinuxMain.swift b/swift-from-go/Tests/LinuxMain.swift new file mode 100644 index 0000000..047f676 --- /dev/null +++ b/swift-from-go/Tests/LinuxMain.swift @@ -0,0 +1,7 @@ +import XCTest + +import go_swiftTests + +var tests = [XCTestCaseEntry]() +tests += go_swiftTests.allTests() +XCTMain(tests) \ No newline at end of file diff --git a/swift-from-go/Tests/go-swiftTests/XCTestManifests.swift b/swift-from-go/Tests/go-swiftTests/XCTestManifests.swift new file mode 100644 index 0000000..796d421 --- /dev/null +++ b/swift-from-go/Tests/go-swiftTests/XCTestManifests.swift @@ -0,0 +1,9 @@ +import XCTest + +#if !os(macOS) +public func allTests() -> [XCTestCaseEntry] { + return [ + testCase(go_swiftTests.allTests), + ] +} +#endif \ No newline at end of file diff --git a/swift-from-go/Tests/go-swiftTests/go_swiftTests.swift b/swift-from-go/Tests/go-swiftTests/go_swiftTests.swift new file mode 100644 index 0000000..b16415b --- /dev/null +++ b/swift-from-go/Tests/go-swiftTests/go_swiftTests.swift @@ -0,0 +1,15 @@ +import XCTest +@testable import go_swift + +final class go_swiftTests: XCTestCase { + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct + // results. + XCTAssertEqual(go_swift().text, "Hello, World!") + } + + static var allTests = [ + ("testExample", testExample), + ] +} diff --git a/swift-from-go/include/go_swift.h b/swift-from-go/include/go_swift.h new file mode 100644 index 0000000..eeb7440 --- /dev/null +++ b/swift-from-go/include/go_swift.h @@ -0,0 +1,2 @@ +// Manually crafted header file for C Library +void sayHello(char* name); \ No newline at end of file diff --git a/swift-from-go/main.go b/swift-from-go/main.go new file mode 100644 index 0000000..788c794 --- /dev/null +++ b/swift-from-go/main.go @@ -0,0 +1,22 @@ +package main + +/* +#cgo CFLAGS: -I./include +#cgo LDFLAGS: -L.build/debug/ -lgo_swift +#include +#include "include/go_swift.h" +*/ +import "C" +import "unsafe" + +func main() { + // Convert Go string to C string + cstr := C.CString("Bob") + + // Call Swift function `sayHello`` + C.sayHello(cstr) + + // The C string is allocated in the C heap using malloc. + // Therefore memory must be freed when we're done + C.free(unsafe.Pointer(cstr)) +}