All Projects → RockfordWei → CSwift

RockfordWei / CSwift

Licence: Apache-2.0 License
C Module for Swift, Swift Script and Dynamic Library Call;Swift中直接调用C语言源程序的展示程序

Programming Languages

swift
15916 projects
shell
77523 projects
c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to CSwift

Antara Gaming Sdk
Komodo Gaming Software Development Kit
Stars: ✭ 51 (+10.87%)
Mutual labels:  module, clang
Rocketcocoa
A framework for running any extra Cocoa code dynamically
Stars: ✭ 187 (+306.52%)
Mutual labels:  dynamic-programming, hotfix
VARGEN
Сheat for CS:GO. Based on Osiris - https://github.com/danielkrupinski/Osiris
Stars: ✭ 12 (-73.91%)
Mutual labels:  dll
xcframework-maker
macOS utility for converting fat-frameworks to SPM-compatible XCFramework with arm64-simulator support
Stars: ✭ 239 (+419.57%)
Mutual labels:  spm
ngx-ionic-image-viewer
An Ionic 4 Angular component to view & zoom on images and photos without any additional dependencies.
Stars: ✭ 129 (+180.43%)
Mutual labels:  module
Java-Questions-and-Solutions
This repository aims to solve and create new problems from different spheres of coding. A path to help students to get access to solutions and discuss their doubts.
Stars: ✭ 34 (-26.09%)
Mutual labels:  dynamic-programming
DTOnboarding
A macOS onboarding component
Stars: ✭ 21 (-54.35%)
Mutual labels:  spm
ci4-album
🔥 CodeIgniter 4 example Album module uses Domain Driven Design Architecture with Tactical Pattern
Stars: ✭ 67 (+45.65%)
Mutual labels:  module
Hippolyte
HTTP Stubbing in Swift
Stars: ✭ 109 (+136.96%)
Mutual labels:  spm
bow-lite
🏹 Bow Lite is a cross-platform library for Typed Functional Programming in Swift
Stars: ✭ 27 (-41.3%)
Mutual labels:  spm
mutator
mutator is an experimental suite of tools aimed at analysis and automation of C/C++ code development
Stars: ✭ 62 (+34.78%)
Mutual labels:  clang
vscode-requirejs
Provides goto definition functionality for require js modules.
Stars: ✭ 20 (-56.52%)
Mutual labels:  module
htmlgo
Type safe and modularize way to generate html on server side.
Stars: ✭ 43 (-6.52%)
Mutual labels:  module
clang-format-editor
Clang-Format Editor is a tool that helps you find the best Clang-Format Style for your C++, C#, Java, JavaScript, and Objective-C code.
Stars: ✭ 15 (-67.39%)
Mutual labels:  clang
textureldr
open source, integrated texture pack management system for geometry dash
Stars: ✭ 30 (-34.78%)
Mutual labels:  dll
HistoryPx
Extended History Information and Last Output Support in PowerShell
Stars: ✭ 62 (+34.78%)
Mutual labels:  module
webtrees-pedigree-chart
SVG based pedigree chart module for webtrees genealogy application.
Stars: ✭ 24 (-47.83%)
Mutual labels:  module
alibabacloud-tairjedis-sdk
alibabacloud-tairjedis-sdk
Stars: ✭ 30 (-34.78%)
Mutual labels:  module
concurrency-kit
🚄 Concurrency abstractions framework for Apple Platforms [Task, Atomic, Lock, Operation, etc.].
Stars: ✭ 17 (-63.04%)
Mutual labels:  spm
NetworkAgent
This package is meant to make http request of an easy way inspiren in the architecture of Moya package. This package is 100% free of dependencies and works with Combine api + Codable
Stars: ✭ 16 (-65.22%)
Mutual labels:  spm

C Module for Swift, Swift Script and Dynamic Library Call 简体中文

Rockford Wei,2017-01-17

Last update: 2018-01-23

This project demonstrates how to call a customized C library in your swift project. You can clone it from github, or follow the instruction below to generate it step by step.

Furthermore, this demo also shows how to use swift as a script, with examples of calling C api as dynamic libraries. This practice makes it possible to patch hot fixes for server side swift without stopping the server, theoretically.

Introduction

There are two C files: CSwift.c and CSwift.h. The objective is to build a CSwift library and export it to Swift.

Quick Start

Please compile this project with Swift 4.0.3 toolchain.

Build & Test

$ git clone https://github.com/RockfordWei/CSwift.git
$ cd CSwift
$ swift build
$ swift test

The sources are written in C while the test program is written in Swift. So if all tests passed, then congratulations! You've already mastered the process to call C api in a Swift source.

Walk Through

However, even without the sources above, you can still start everything from blank:

Start From An Empty Folder:

Assume the objective library is still CSwift, then find an empty folder and try these commands in a terminal:

mkdir CSwift && cd CSwift && swift package init
mkdir Sources/CSwift/include && rm Sources/CSwift/CSwift.swift

The above commands will set up the empty project template

C Header File

Now edit the header file Sources/CSwift/include/Swift.h:

extern int c_add(int, int);
#define C_TEN 10

C Source

Finishing the implementation of the C body Sources/CSwift/CSwift.c:

#include "include/CSwift.h"
int c_add(int a, int b) { return a + b ; }

Module Map

Next, we will setup an umbrella file for swift: Sources/CSwift/include/module.modulemap

module CSwift [system] {
  header "CSwift.h"
  export *
}

Call C API in Swift

Now let's check if the library works by editing a test script: Tests/CSwiftTests/CSwiftTests.swift

import XCTest
@testable import CSwift
class CSwiftTests: XCTestCase {
  func testExample() {
    let three = c_add(1, 2)
    XCTAssertEqual(three, 3)
    XCTAssertEqual(C_TEN, 10)
  }
  static var allTests : [(String, (CSwiftTests) -> () throws -> Void)] {
      return [  ("testExample", testExample)  ]
  }
}

Test

The final step is the easiest one - build & test:

$ swift build
$ swift test

If success, then perfect!

Swift as Script and Call C lib dynamically

Beside the above classic static build & run, Swift also provide an interpreter to execute swift source as scripts, just like a playground in a terminal. This project also makes an example for swift script, and even more, introduces how to call the same C api dynamically in such a script.

Dynamic Link Library

The default linking object of Swift 4 is static, so it needs a bit modification to turn it into a dynamic one.

To do this, edit the Package.swift file, and add a line:

.library(
    name: "CSwift",
    type: .`dynamic`,  // <------------ Insert the dynamic type right here!
    targets: ["CSwift"]),

Please check a swift script dll.swift.script, actually it is a common swift with no difference to any other swift sources:

// First thing first, make sure your dll path is an dynamic library in an ABSOLUTE path.
// on Mac, the suffix is ".dylib"; on Linux, it is ".so"
guard let lib = dlopen(dllpath,  RTLD_LAZY) else {
  exit(0)
}

// declare the api prototype to call
typealias AddFunc = @convention(c) (CInt, CInt) -> CInt

// look up the function in the library
guard let c_add = dlsym(lib, "c_add") else {
  dlclose(lib)
  exit(0)
}

// attache the function to the real API address
let add = unsafeBitCast(c_add, to: AddFunc.self)

// call the C method, dynamically
let x = add(1, 2)
print(x)

// release resources
dlclose(lib)

Run the Swift Script

This project also provides a bash script dll.sh to run the swift script above.

# step one, build the C library
swift build

# then test what OS it is: .dylib for apple and .so for linux
if swift --version|grep apple
then
  SUFFIX=dylib
else
  SUFFIX=so
fi

# generate the full path of new library.
DLL=$PWD/.build/debug/libCSwift.$SUFFIX

# run the swift script and call the libray.
swift dll.swift.script $DLL

More Info

If Xcode is preferred, then try command swift package generate-xcodeproj before building.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].