0.5.0 • Published 1 year ago

@bitair/linker.c v0.5.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Intro

Linker.c is a dynamic C library linker that provides an interface for accessing any C-shared libraries. Accessing C, C++, Go, and Rust libraries has been covered in the sample section.

Important Note: Linker.c is only compatible with Linux-based operating systems.

Usage

Install

sudo apt update && sudo apt -y install build-essential autoconf automake libtool
npm i @bitair/linker.c

Sample

Node.js side

index.js

const { link, ReturnType } = require('@bitair/linker.c')

const libPath = __dirname + './lib.so'
const { add } = link(libPath, {
  add: ReturnType.Number
})

console.log(add(5, 3))

C side

lib.c

double add(double val1, double val2) {
  return val1 + val2;
}

build.sh

gcc -c -fPIC lib.c && gcc -shared -o lib.so lib.o

C++ side

lib.cpp

double cpp_add(double val1, double val2)
{
  return val1 + val2;
}

extern "C"
{
  double add(double val1, double val2)
  {
    return cpp_add(val1, val2);
  }
}

build.sh

gcc -c -fPIC lib.cpp && gcc -shared -o lib.so lib.o

Go side

lib.go

package main

import "C"

func go_add(x float64, y float64) float64 {
	return x + y
}

//export add
func add(x C.double, y C.double) C.double {
	return C.double(go_add(float64(x), float64(y)))
}

func main() {}

build.sh

go build -o lib.so -buildmode=c-shared lib.go

Rust side

lib.rs

use libc::c_double;

fn rs_add(val1: f64, val2: f64) -> f64 {
    val1 + val2
}

#[no_mangle]
pub extern "C" fn add(val1: c_double, val2: c_double) -> c_double {
    return rs_add(val1, val2);
}

Cargo.toml

[lib]
crate-type = ["cdylib"]

[dependencies]
libc = "0.2"

build.sh

cargo build

API

link(libPath: string, functions: SignatureDict): Proxy

Links to a shared library and returns a proxy for accessing its functions.

  • libPath: string

    Path of the shared library.

  • functions: SignatureDict

    Signatures of the foreign functions. Note that the types of a function parameters would be inferred at the call time from the passing arguments.

type SignatureDict = {
  [key: string]: ReturnType
}
  • key: string

    Name of the foreign function.

  • ReturnType

    Type of the return value.

type Proxy = {
  [key: string]: (...params: unknown[]) => unknown
}
  • key: string

    Name of the foreign function.

  • (...params:unknown[]) => unknown

    The function's invoker.

enum ReturnType {
  ArrayBuffer,
  Boolean,
  Number,
  String
}

Supported types and type mapping

JSC
ArrayBufferstruct Buffer
booleanbool
numberdouble
string (UTF-8)char *
typedef struct {
  void* data;
  size_t len;
} Buffer;

Please see the test folder for a complete sample code.

License

MIT License