Skip to content
This repository has been archived by the owner on Dec 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4 from MGTheTrain/feature/implement-rust-binding-…
Browse files Browse the repository at this point in the history
…for-core-module

[Feature] - Implement rust binding for core module
  • Loading branch information
MGTheTrain authored Apr 16, 2024
2 parents 0917571 + 3feb3c6 commit 9125be0
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 22 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ secrets.cfg
*.so
__pycache__
obj
bin
bin
Cargo.lock
target
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.4.0] - 16-04-2024

### Added

- [Feature] Sample Rust wrappers utilizing [cxx](https://crates.io/crates/cxx) and refering to C++ source code

## [0.3.0] - 16-04-2024

### Added
Expand Down
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ A collection of sample code snippets demonstrating how to create bindings for va
## Reference

- [Python Bindings: Calling C or C++ From Python](https://realpython.com/python-bindings-overview/)
- [CXX — safe FFI between Rust and C++](https://crates.io/crates/cxx)

## Features

- [x] Modular code base
- [x] CI workflows for QA
- [x] Sample Python wrappers refering to C++ compiled source code resulting in shared libraries
- [ ] Sample Rust wrappers refering to C++ compiled source code resulting in shared libraries
- [x] Sample Python wrappers refering to C++ compiled source code resulting in shared libraries
- [x] Sample Rust wrappers utilizing [cxx](https://crates.io/crates/cxx) and refering to C++ source code
- [x] Sample Go wrappers refering to C++ compiled source code resulting in shared libraries
- [x] Sample C# wrappers refering to C++ compiled source code resulting in shared libraries
- [ ] C++ audio module **(Optional, Experimental)**
Expand Down Expand Up @@ -71,12 +72,40 @@ cd devops\scripts\ps1

#### Python

Navigate to the [bindings python folder](./bindings/python) after C++ source code compilation and run `python main.py --path <path to libcore_wrapper.so>`
After C++ source code compilation resuting in a shared library, run:

```sh
cd bindings/python
python main.py --path <path to libcore_wrapper.so>
```

#### C#

Navigate to the [bindings c# folder](./bindings/csharp) after C++ source code compilation and follow comments in [Program.cs](./bindings/csharp/Mgtt.CoreWrapper/Program.cs)
After C++ source code compilation resuting in a shared library, run:

```sh
cd bindings/csharp
dotnet build
# Copy on unix systems the libcore_wrapper.so to the `bindings/c#/Mgtt.CoreWrapper/bin/Debug/net8.0` folder
dotnet run
```

#### Go

Navigate to the [bindings go folder](./bindings/go) after C++ source code compilation and follow comments in [main.go](./bindings/go/main.go)
After C++ source code compilation resuting in a shared library, run:

```sh
cd bindings/go
# Copy in the devcontainer the libcore_wrapper.so to this folder
export LD_LIBRARY_PATH=/workspaces/cpp-sample-bindings/bindings/go/libcore_wrapper.so:$LD_LIBRARY_PATH
go run main.go
```

#### Rust

Run (does not consider a shared library from compiled C++ source code):

```sh
cd bindings/rust
cargo run
```
6 changes: 1 addition & 5 deletions bindings/csharp/Mgtt.CoreWrapper/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,4 @@ static int Main(string[] args)

return 0;
}
}

// 0. Execute `dotnet build`
// 1. Copy on unix systems the libcore_wrapper.so to the `bindings/c#/Mgtt.CoreWrapper/bin/Debug/net8.0` folder
// 2. Run `dotnet run`
}
6 changes: 1 addition & 5 deletions bindings/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ package main
// #include <math-utils.h>
import "C"
import (
"fmt"
"fmt"
)

func main() {
Expand All @@ -51,7 +51,3 @@ func main() {
circumference := C.getCircleCircumference(C.float(radius))
fmt.Println("Circle circumference:", circumference)
}

// 0. Copy in the devcontainer the libcore_wrapper.so to this folder
// 1. In the devcontainer `export LD_LIBRARY_PATH=/workspaces/cpp-sample-bindings/bindings/go/libcore_wrapper.so:$LD_LIBRARY_PATH`
// 2. Run executable `go run main.go`
5 changes: 1 addition & 4 deletions bindings/python/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,4 @@ def main(path):
if not args.path:
parser.error('Please provide the path to the core wrapper library using --path')

main(args.path)

# 0. Copy on unix systems the libcore_wrapper.so to a desired destination folder
# 1. Run `python main.py --path <path to libcore_wrapper.so>`
main(args.path)
Empty file removed bindings/rust/.gitignore
Empty file.
12 changes: 12 additions & 0 deletions bindings/rust/cxx-sample/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "cxx-sample"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cxx = "1.0"

[build-dependencies]
cxx-build = "1.0"
32 changes: 32 additions & 0 deletions bindings/rust/cxx-sample/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// The MIT License
//
// Copyright (c) 2024 MGTheTrain
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

fn main() {
cxx_build::bridge("src/main.rs")
.file("src/math-utils.cc")
.std("c++14")
.compile("cxxbridge-core");

println!("cargo:rerun-if-changed=src/main.rs");
println!("cargo:rerun-if-changed=src/math-utils.cc");
println!("cargo:rerun-if-changed=include/math-utils.h");
}
80 changes: 80 additions & 0 deletions bindings/rust/cxx-sample/include/math-utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// The MIT License
//
// Copyright (c) 2024 MGTheTrain
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#include <stdint.h>

#ifdef __cplusplus
#define M_PI 3.141
extern "C" {
#endif

/**
* @brief Adds two integers.
* @param a The first integer.
* @param b The second integer.
* @return The sum of a and b.
*/
int32_t add(int32_t a, int32_t b);

/**
* @brief Subtracts one integer from another.
* @param a The integer to subtract from.
* @param b The integer to subtract.
* @return The result of subtracting b from a.
*/
int32_t subtract(int32_t a, int32_t b);

/**
* @brief Multiplies two integers.
* @param a The first integer.
* @param b The second integer.
* @return The product of a and b.
*/
int32_t multiply(int32_t a, int32_t b);

/**
* @brief Divides one float by another.
* @param a The float to divide.
* @param b The divisor.
* @return The result of dividing a by b.
* @throw Division by zero error if b is zero.
*/
float divide(float a, float b);

/**
* @brief Calculates the area of the circle.
* @param radius The radius of the circle.
* @return The area of the circle.
*/
float getCircleArea(float radius);

/**
* @brief Calculates the circumference of the circle.
* @param radius The radius of the circle
* @return The circumference of the circle.
*/
float getCircleCircumference(float radius);
#ifdef __cplusplus
}
#endif
71 changes: 71 additions & 0 deletions bindings/rust/cxx-sample/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// The MIT License
//
// Copyright (c) 2024 MGTheTrain
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use cxx::ExternType;

#[cxx::bridge]
mod ffi {
unsafe extern "C++" {
include!("cxx-sample/include/math-utils.h");
fn add(a: i32, b: i32) -> i32;
fn subtract(a: i32, b: i32) -> i32;
fn multiply(a: i32, b: i32) -> i32;
fn divide(a: f32, b: f32) -> f32;

fn getCircleArea(radius: f32) -> f32;
fn getCircleCircumference(radius: f32) -> f32;
}
}

// missing step: separate lib from app
fn main() {
let a = 10;
let b = 5;
let result_add: i32;
let result_subtract: i32;
let result_multiply: i32;
let result_divide: f32;

unsafe {
result_add = ffi::add(a, b);
result_subtract = ffi::subtract(a, b);
result_multiply = ffi::multiply(a, b);
result_divide = ffi::divide(a as f32, b as f32);
}

println!("{} + {} = {}", a, b, result_add);
println!("{} - {} = {}", a, b, result_subtract);
println!("{} * {} = {}", a, b, result_multiply);
println!("{} / {} = {}", a, b, result_divide);

let radius = 5.0;
let circle_area: f32;
let circle_circumference: f32;

unsafe {
circle_area = ffi::getCircleArea(radius);
circle_circumference = ffi::getCircleCircumference(radius);
}

println!("Area of circle with radius {}: {}", radius, circle_area);
println!("Circumference of circle with radius {}: {}", radius, circle_circumference);
}
Loading

0 comments on commit 9125be0

Please sign in to comment.