Skip to content

Commit

Permalink
Merge pull request #3 from jlieth/main
Browse files Browse the repository at this point in the history
Added support for building as library
  • Loading branch information
spezifisch authored Aug 16, 2024
2 parents 6c636ad + 991ba1b commit 122f5bd
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
18 changes: 15 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,26 @@ jobs:
# build target for rust
echo "TARGET=${{ matrix.target }}" >> $GITHUB_ENV
- name: Build
- name: Build Binary
run: |
cargo build --target "${{ matrix.target }}"
mkdir -p build_output
cp target/${{ matrix.target }}/debug/ifstat-rs${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }} build_output/
- name: Upload built binary
- name: Build Library
run: |
cargo build --target "${{ matrix.target }}" --lib
mkdir -p build_output
# handle different name under windows
if [ "${{ matrix.target }}" != "x86_64-pc-windows-gnu" ]; then
cp target/${{ matrix.target }}/debug/libifstat_rs${{ matrix.target == 'x86_64-pc-windows-gnu' && '.dll' || '.so' }} build_output/
else
cp target/${{ matrix.target }}/debug/ifstat_rs.dll build_output/
fi
- name: Upload built Binary + Library
uses: actions/upload-artifact@v4
with:
name: ifstat-rs-${{ matrix.target }}${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }}
path: build_output/
name: ifstat-rs-${{ matrix.target }}-bundle
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"rust-lang.rust-analyzer",
"tamasfe.even-better-toml"
]
}
19 changes: 19 additions & 0 deletions BUILD_LIBRARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Build as Library

## Instructions

```console
$ sudo apt install build-essential

$ cargo build --lib
Compiling ifstat-rs v3.0.0 (/home/q/ifstat-rs)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.59s

$ file target/debug/libifstat_rs.so
target/debug/libifstat_rs.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e67b0c1d9d1a18a28cd0341a961fff3ded1d29f7, with debug_info, not stripped

$ objdump -x target/debug/libifstat_rs.so|grep GetNet
0000000000015750 g F .text 0000000000000141 GetNetDevStats
$ objdump -x target/debug/libifstat_rs.so|grep FreeCStr
00000000000158a0 g F .text 000000000000003b FreeCString
```
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ os_pipe = "1.2.1"
indexmap = "2.3.0"
libc = "0.2.155"

[lib]
name = "ifstat_rs"
path = "src/lib.rs"
crate-type = ["lib", "cdylib"]

[target.'cfg(windows)'.dependencies]
windows = { version = "0.58.0", features = [
"Win32_Foundation",
Expand Down
50 changes: 50 additions & 0 deletions src/net_stats/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
use indexmap::IndexMap;
use libc::c_char;
use std::ffi::CString;
use std::ptr;

#[cfg(target_os = "linux")]
mod linux_impl;
#[cfg(target_os = "macos")]
Expand All @@ -11,3 +16,48 @@ pub use linux_impl::*;
pub use macos_impl::*;
#[cfg(target_os = "windows")]
pub use windows_impl::*;

// Helper function to convert Rust String to C string (raw pointer)
fn string_to_c_string(s: String) -> *mut c_char {
let c_string = CString::new(s).unwrap();
c_string.into_raw()
}

// Converts the statistics into a format that can be returned to LabVIEW
fn convert_stats_to_c(stats: IndexMap<String, (u64, u64)>) -> *mut c_char {
let mut output = String::new();
for (device, (received, transmitted)) in stats {
output.push_str(&format!(
"{},{},{}\n",
device, received, transmitted
));
}
string_to_c_string(output)
}

#[no_mangle]
pub extern "C" fn GetNetDevStats() -> *mut c_char {
// Call the platform-specific implementation of `get_net_dev_stats`
let stats = get_net_dev_stats();

// Check if the `stats` is valid (not an error)
match stats {
Ok(stats_map) => {
// Convert the stats to a C string format and return the pointer
convert_stats_to_c(stats_map)
}
Err(_) => {
// On error, return a null pointer
ptr::null_mut()
}
}
}

#[no_mangle]
pub extern "C" fn FreeCString(s: *mut c_char) {
if !s.is_null() {
unsafe {
let _ = CString::from_raw(s); // This will automatically free the memory
}
}
}

0 comments on commit 122f5bd

Please sign in to comment.