Fixed rust, named the libraries sdk's, better examples
This commit is contained in:
parent
407faab33a
commit
f55279b7ef
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
/target
|
/target
|
||||||
/plugins
|
/plugins
|
||||||
/.cache
|
/.cache
|
||||||
|
compile_commands.json
|
||||||
|
|
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -51,6 +51,12 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -122,9 +128,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dim_plugin_helper"
|
name = "dim_sdk"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -157,7 +164,7 @@ dependencies = [
|
||||||
name = "example_rust"
|
name = "example_rust"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dim_plugin_helper",
|
"dim_sdk",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
workspace = { members = [ "dim_plugin_helper","dim_plugins/example_rust"] }
|
workspace = { members = [ "sdk/rust","dim_plugins/example_rust"] }
|
||||||
[package]
|
[package]
|
||||||
name = "dim"
|
name = "dim"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -4,7 +4,7 @@ CWD := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
PLUGIN_DIR = ${CWD}plugins
|
PLUGIN_DIR = ${CWD}plugins
|
||||||
OBJECT_DIR = $(CWD)target/objects
|
OBJECT_DIR = $(CWD)target/objects
|
||||||
BUILD_DIR = $(CWD)target
|
BUILD_DIR = $(CWD)target
|
||||||
DIM_CC_FLAGS = -I$(CWD)include -rdynamic -shared -fPIC
|
DIM_CC_FLAGS = -I$(CWD)sdk/c_cxx
|
||||||
DIM_CC = gcc
|
DIM_CC = gcc
|
||||||
|
|
||||||
BIN=$(BUILD_DIR)/dim
|
BIN=$(BUILD_DIR)/dim
|
||||||
|
@ -21,7 +21,7 @@ target/release/dim:
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
dim_plugins/%/Makefile:
|
dim_plugins/%/Makefile:
|
||||||
$(MAKE) -C $(dir $@) \
|
@$(MAKE) -C $(dir $@) \
|
||||||
-E "PLUGIN_DIR=$(PLUGIN_DIR)" \
|
-E "PLUGIN_DIR=$(PLUGIN_DIR)" \
|
||||||
-E "OBJECT_DIR=$(OBJECT_DIR)" \
|
-E "OBJECT_DIR=$(OBJECT_DIR)" \
|
||||||
-E "BUILD_DIR=$(BUILD_DIR)" \
|
-E "BUILD_DIR=$(BUILD_DIR)" \
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
"-o",
|
"-o",
|
||||||
"/home/mcorange/@Projects/xor64/dim/target/objects/example_c/main.o",
|
"/home/mcorange/@Projects/xor64/dim/target/objects/example_c/main.o",
|
||||||
"src/main.c",
|
"src/main.c",
|
||||||
"-fPIC",
|
"-pie",
|
||||||
"-pie"
|
"-I/home/mcorange/@Projects/xor64/dim/sdk/c_cxx",
|
||||||
|
"-fPIC"
|
||||||
],
|
],
|
||||||
"file": "src/main.c"
|
"file": "src/main.c"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
use std::{ffi::{c_char, c_void, CStr, CString}, io::Write};
|
|
||||||
|
|
||||||
pub use libc::snprintf;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PluginInfo {
|
|
||||||
ptrs: PluginInfoPtrs,
|
|
||||||
c_name: CString,
|
|
||||||
c_version: CString,
|
|
||||||
c_license: CString
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct PluginInfoPtrs {
|
|
||||||
name: *const c_char,
|
|
||||||
version: *const c_char,
|
|
||||||
license: *const c_char,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PluginInfo {
|
|
||||||
// pub fn new() -> Self {
|
|
||||||
// Self {
|
|
||||||
// name: std::ptr::null(),
|
|
||||||
// version: std::ptr::null(),
|
|
||||||
// license: std::ptr::null(),
|
|
||||||
// c_name: Default::default(),
|
|
||||||
// c_version: Default::default(),
|
|
||||||
// c_license: Default::default()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
pub fn new(name: &str, version: &str, license: &str) -> Self {
|
|
||||||
|
|
||||||
let c_name = CString::new(name).unwrap();
|
|
||||||
let c_version = CString::new(version).unwrap();
|
|
||||||
let c_license = CString::new(license).unwrap();
|
|
||||||
let name = c_name.as_ptr();
|
|
||||||
let version = if c_version.is_empty() {
|
|
||||||
std::ptr::null()
|
|
||||||
} else {c_version.as_ptr()};
|
|
||||||
let license = if c_license.is_empty() {
|
|
||||||
std::ptr::null()
|
|
||||||
} else {c_license.as_ptr()};
|
|
||||||
|
|
||||||
Self { ptrs: PluginInfoPtrs{ name, version, license }, c_name, c_version, c_license }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self) -> *const c_void {
|
|
||||||
&self.ptrs as *const _ as *const c_void
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe impl Sync for PluginInfo {}
|
|
||||||
|
|
||||||
|
|
||||||
// Lord have mercy on me
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! plugin_info {
|
|
||||||
($name:literal, $version:literal, $license:literal) => {
|
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
|
||||||
static ref PLUGIN_INFO: PluginInfo = PluginInfo::new($name, $version, $license);
|
|
||||||
);
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct CBuffer {
|
|
||||||
inner: *mut i8,
|
|
||||||
count: usize,
|
|
||||||
capacity: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CBuffer {
|
|
||||||
pub fn from_raw_parts_mut(buf: *mut i8, capacity: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: buf,
|
|
||||||
capacity,
|
|
||||||
count: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl Write for CBuffer {
|
|
||||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
for c in buf {
|
|
||||||
unsafe {
|
|
||||||
if self.count + count >= self.capacity - 1 {
|
|
||||||
return Err(std::io::ErrorKind::OutOfMemory.into());
|
|
||||||
}
|
|
||||||
(*self.inner.add(self.count + count)) = *c as i8;
|
|
||||||
}
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
(*self.inner.add(self.count + count)) = 0;
|
|
||||||
}
|
|
||||||
self.count += count;
|
|
||||||
|
|
||||||
Ok(count as usize)
|
|
||||||
}
|
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
PLUGIN_NAME=example_c
|
PLUGIN_NAME=example_c
|
||||||
|
|
||||||
|
|
||||||
CC_FLAGS = $(DIM_CC_FLAGS)
|
CC_FLAGS = $(DIM_CC_FLAGS) -fPIC
|
||||||
|
|
||||||
SOURCES=$(wildcard src/*.c)
|
SOURCES=$(wildcard src/*.c)
|
||||||
OBJECTS=$(patsubst src/%.c,$(OBJECT_DIR)/$(PLUGIN_NAME)/%.o,$(SOURCES))
|
OBJECTS=$(patsubst src/%.c,$(OBJECT_DIR)/$(PLUGIN_NAME)/%.o,$(SOURCES))
|
||||||
|
@ -12,8 +12,8 @@ build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||||
|
|
||||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECTS)
|
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECTS)
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(DIM_CC) -o $@ $^ $(CC_FLAGS)
|
$(DIM_CC) -o $@ $^ -rdynamic -shared $(CC_FLAGS)
|
||||||
|
|
||||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/%.o: src/%.c
|
$(OBJECT_DIR)/$(PLUGIN_NAME)/%.o: src/%.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(DIM_CC) -c -o $@ $< -fPIC -pie
|
$(DIM_CC) -c -o $@ $< -pie $(CC_FLAGS)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "../../../include/plug.h"
|
#include "dim_sdk.h"
|
||||||
|
|
||||||
PLUG_INFO("Example plugin", "0.0.0", "GPLv3")
|
PLUG_INFO("Example plugin", "0.0.1", "GPLv3")
|
||||||
|
|
||||||
typedef struct plug_t {
|
typedef struct plug_t {
|
||||||
char* some_data;
|
char* some_data;
|
||||||
|
@ -16,7 +16,6 @@ plug_t* p = {0};
|
||||||
void plug_init() {
|
void plug_init() {
|
||||||
p = malloc(sizeof(plug_t));
|
p = malloc(sizeof(plug_t));
|
||||||
assert(p != NULL && "Buy more ram KEKW");
|
assert(p != NULL && "Buy more ram KEKW");
|
||||||
p->some_data = "hi :3";
|
|
||||||
p->count = 0;
|
p->count = 0;
|
||||||
|
|
||||||
printf("Hello from plugin");
|
printf("Hello from plugin");
|
||||||
|
@ -31,7 +30,7 @@ void plug_post_reload(void *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void plug_poll(char *buf, size_t len) {
|
void plug_poll(char *buf, size_t len) {
|
||||||
snprintf(buf, len, "%s (%d)", p->some_data, p->count++);
|
snprintf(buf, len, "Hello from C! (%d)", p->count++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void plug_free() {
|
void plug_free() {
|
||||||
|
|
|
@ -8,5 +8,5 @@ crate-type=["cdylib"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dim_plugin_helper = {path="../../dim_plugin_helper"}
|
dim_sdk = {path="../../sdk/rust/"}
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
|
@ -4,12 +4,12 @@ PLUGIN_NAME=example_rust
|
||||||
|
|
||||||
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
build: $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||||
|
|
||||||
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/release/lib$(PLUGIN_NAME).so
|
$(PLUGIN_DIR)/$(PLUGIN_NAME).dim: $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so
|
||||||
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/release/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
cp $(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so $(PLUGIN_DIR)/$(PLUGIN_NAME).dim
|
||||||
|
|
||||||
$(OBJECT_DIR)/$(PLUGIN_NAME)/release/lib$(PLUGIN_NAME).so:
|
$(OBJECT_DIR)/$(PLUGIN_NAME)/debug/lib$(PLUGIN_NAME).so:
|
||||||
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
mkdir -p $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||||
cargo build --release --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
cargo build --target-dir $(OBJECT_DIR)/$(PLUGIN_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,67 +1,48 @@
|
||||||
use std::ffi::c_void;
|
use std::fmt::Write;
|
||||||
use std::ffi::CStr;
|
use dim_sdk::{plugin_info, DimPlugin};
|
||||||
use std::ffi::CString;
|
|
||||||
use std::io::BufWriter;
|
|
||||||
use std::io::Write;
|
|
||||||
use dim_plugin_helper::{plugin_info, PluginInfo};
|
|
||||||
|
|
||||||
plugin_info!("Example rust project", "owo", "nyaaa");
|
plugin_info!(
|
||||||
|
Plug, // Your main global structs name that implements `DimPlugin`
|
||||||
|
"Example rust project", // Plugin name
|
||||||
|
"0.0.0", // Plugin Version (leave empty for none)
|
||||||
|
"GPLv3" // Plugin license (leave empty for none)
|
||||||
|
);
|
||||||
|
|
||||||
struct Plug {
|
struct Plug {
|
||||||
pub some_data: String,
|
counter: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plug {
|
impl Plug {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
some_data: String::from("OwO")
|
counter: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DimPlugin for Plug {
|
||||||
static mut PLUG: *mut Plug = std::ptr::null_mut();
|
fn init(&mut self) {
|
||||||
|
// Initialise data, this will run once, it will not run again after reload
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn plug_get_info() -> *const c_void {
|
|
||||||
PLUGIN_INFO.get()
|
|
||||||
}
|
}
|
||||||
|
fn poll(&mut self, f: &mut dim_sdk::CBuffer) -> dim_sdk::Result<()> {
|
||||||
#[no_mangle]
|
// Write to buffer the text you want to display, keep this short
|
||||||
extern "C" fn plug_init() {
|
write!(f, "Hello from rust! ({})", self.counter)?;
|
||||||
unsafe {
|
self.counter += 1;
|
||||||
PLUG = (&mut Plug::new()) as *mut Plug;
|
Ok(())
|
||||||
|
}
|
||||||
|
fn pre_reload(&mut self) {
|
||||||
|
// Do stuff before reload, probably save important things because theres a good chance
|
||||||
|
// (especially on rust) that if you change the data layout it will die
|
||||||
|
}
|
||||||
|
fn post_reload(&mut self) {
|
||||||
|
// Do stuff after reloading plugin, state a.k.a this struct has the same data, will crash
|
||||||
|
// if the data layout changed
|
||||||
|
}
|
||||||
|
fn free(&mut self) {
|
||||||
|
// Yout probably dont need this but its for freeing things before the plugin gets unloaded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn plug_pre_reload() -> *const () {
|
|
||||||
unsafe {
|
|
||||||
return PLUG as *const ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn plug_post_reload(state: *mut ()) {
|
|
||||||
unsafe {
|
|
||||||
PLUG = state as *mut Plug;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn plug_poll(buf: *mut i8, len: usize) {
|
|
||||||
let mut buf = dim_plugin_helper::CBuffer::from_raw_parts_mut(buf, len);
|
|
||||||
// let mut buf = StringBuffer::from_raw_parts_mut(buf, len);
|
|
||||||
|
|
||||||
let data = unsafe {(*PLUG).some_data.clone()};
|
|
||||||
|
|
||||||
let _ = write!(buf, "{}", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn plug_free() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "../include/plug.h"
|
|
||||||
|
|
||||||
PLUG_NAME("Example plugin")
|
|
||||||
PLUG_VERSION("0.0.0")
|
|
||||||
PLUG_LICENSE("GPLv3")
|
|
||||||
|
|
||||||
typedef struct plug_t {
|
|
||||||
char* some_data;
|
|
||||||
} plug_t;
|
|
||||||
|
|
||||||
static plug_t* p = {0};
|
|
||||||
|
|
||||||
void plug_init() {
|
|
||||||
p = malloc(sizeof(plug_t));
|
|
||||||
assert(p != NULL && "Buy more ram KEKW");
|
|
||||||
p->some_data = "hi :3";
|
|
||||||
}
|
|
||||||
|
|
||||||
void* plug_pre_reload() {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void plug_post_reload(void *state) {
|
|
||||||
p = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void plug_poll(char *buf, size_t len) {
|
|
||||||
snprintf(buf, len, "%s", p->some_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void plug_free() {
|
|
||||||
free(p);
|
|
||||||
}
|
|
|
@ -1,12 +1,13 @@
|
||||||
[package]
|
[package]
|
||||||
name = "dim_plugin_helper"
|
name = "dim_sdk"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name="dim_plugin_helper"
|
name="dim_sdk"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.86"
|
||||||
bytes = "1.6.0"
|
bytes = "1.6.0"
|
||||||
lazy_static = { version = "1.4.0", features = ["spin"] }
|
lazy_static = { version = "1.4.0", features = ["spin"] }
|
||||||
libc = "0.2.155"
|
libc = "0.2.155"
|
36
sdk/rust/src/c_buffer.rs
Normal file
36
sdk/rust/src/c_buffer.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CBuffer<'a> {
|
||||||
|
inner: &'a mut [i8],
|
||||||
|
count: usize,
|
||||||
|
capacity: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // rust_analyzer too dumb to see my macro magic
|
||||||
|
// i hate that macro as much as you do
|
||||||
|
impl CBuffer<'_> {
|
||||||
|
pub fn from_raw_parts_mut(buf: *mut i8, capacity: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: unsafe {
|
||||||
|
std::slice::from_raw_parts_mut(buf, capacity)
|
||||||
|
},
|
||||||
|
capacity,
|
||||||
|
count: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl std::fmt::Write for CBuffer<'_> {
|
||||||
|
fn write_str(&mut self, buf: &str) -> Result<(), std::fmt::Error> {
|
||||||
|
for c in buf.as_bytes() {
|
||||||
|
if self.count >= self.capacity - 1 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
self.inner[self.count] = *c as i8;
|
||||||
|
self.count += 1;
|
||||||
|
}
|
||||||
|
self.inner[self.count] = 0;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
25
sdk/rust/src/lib.rs
Normal file
25
sdk/rust/src/lib.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod magic;
|
||||||
|
mod c_buffer;
|
||||||
|
mod plugin_info;
|
||||||
|
|
||||||
|
pub use c_buffer::*;
|
||||||
|
pub use plugin_info::*;
|
||||||
|
|
||||||
|
pub use anyhow::Result;
|
||||||
|
|
||||||
|
pub trait DimPlugin {
|
||||||
|
fn init(&mut self);
|
||||||
|
fn pre_reload(&mut self);
|
||||||
|
fn post_reload(&mut self);
|
||||||
|
fn poll(&mut self, f: &mut CBuffer) -> Result<()>;
|
||||||
|
fn free(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
53
sdk/rust/src/magic.rs
Normal file
53
sdk/rust/src/magic.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Lord have mercy on me
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! plugin_info {
|
||||||
|
($typ:ty, $name:literal, $version:literal, $license:literal) => {
|
||||||
|
|
||||||
|
lazy_static::lazy_static!(
|
||||||
|
static ref PLUGIN_INFO: $crate::PluginInfo = $crate::PluginInfo::new($name, $version, $license);
|
||||||
|
);
|
||||||
|
|
||||||
|
static mut PLUG: *mut $typ = std::ptr::null_mut() as *mut $typ;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_get_info() -> *const std::ffi::c_void {
|
||||||
|
PLUGIN_INFO.get_raw_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_init() {
|
||||||
|
PLUG = std::alloc::alloc(std::alloc::Layout::new::<$typ>()) as *mut $typ;
|
||||||
|
*PLUG = Plug::new();
|
||||||
|
(&mut *PLUG).init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_pre_reload() -> *mut $typ {
|
||||||
|
//TODO: Untested
|
||||||
|
(&mut *PLUG).pre_reload();
|
||||||
|
return PLUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_post_reload(state: *mut $typ) {
|
||||||
|
//TODO: Untested
|
||||||
|
PLUG = state;
|
||||||
|
(&mut *PLUG).post_reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_poll(buf: *mut i8, len: std::ffi::c_uint) {
|
||||||
|
let mut buf = $crate::CBuffer::from_raw_parts_mut(buf, len as usize);
|
||||||
|
if let Err(_e) = (&mut *PLUG).poll(&mut buf) {
|
||||||
|
// TODO: Handle error maybe?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn plug_free() {
|
||||||
|
std::alloc::dealloc(PLUG as *mut u8, std::alloc::Layout::new::<$typ>());
|
||||||
|
(&mut *PLUG).free();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
41
sdk/rust/src/plugin_info.rs
Normal file
41
sdk/rust/src/plugin_info.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use std::ffi::{c_char, c_void, CString};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PluginInfo {
|
||||||
|
ptrs: PluginInfoPtrs,
|
||||||
|
_name: CString,
|
||||||
|
_version: CString,
|
||||||
|
_license: CString
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PluginInfoPtrs {
|
||||||
|
name: *const c_char,
|
||||||
|
version: *const c_char,
|
||||||
|
license: *const c_char,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginInfo {
|
||||||
|
pub fn new(name: &str, version: &str, license: &str) -> Self {
|
||||||
|
|
||||||
|
let _name = CString::new(name).unwrap();
|
||||||
|
let _version = CString::new(version).unwrap();
|
||||||
|
let _license = CString::new(license).unwrap();
|
||||||
|
let name = _name.as_ptr();
|
||||||
|
let version = if _version.is_empty() {
|
||||||
|
std::ptr::null()
|
||||||
|
} else {_version.as_ptr()};
|
||||||
|
let license = if _license.is_empty() {
|
||||||
|
std::ptr::null()
|
||||||
|
} else {_license.as_ptr()};
|
||||||
|
|
||||||
|
Self { ptrs: PluginInfoPtrs{ name, version, license }, _name, _version, _license }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_raw_ptr(&self) -> *const c_void {
|
||||||
|
&self.ptrs as *const _ as *const c_void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe impl Sync for PluginInfo {}
|
||||||
|
|
|
@ -37,6 +37,8 @@ impl PlugMan {
|
||||||
self.load(entry.path().to_path_buf())?;
|
self.load(entry.path().to_path_buf())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("INFO: Loaded {} plugins", self.plugins.len());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,18 +83,18 @@ impl PlugMan {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PluginError {
|
pub enum PluginError {
|
||||||
DlOpenError(dlopen::Error),
|
DlOpenError,
|
||||||
IoError(std::io::Error)
|
IoError
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<dlopen::Error> for PluginError {
|
impl From<dlopen::Error> for PluginError {
|
||||||
fn from(value: dlopen::Error) -> Self {
|
fn from(_: dlopen::Error) -> Self {
|
||||||
Self::DlOpenError(value)
|
Self::DlOpenError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for PluginError {
|
impl From<std::io::Error> for PluginError {
|
||||||
fn from(value: std::io::Error) -> Self {
|
fn from(_: std::io::Error) -> Self {
|
||||||
Self::IoError(value)
|
Self::IoError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{alloc::Layout, ffi::{c_char, CStr, CString}, path::PathBuf};
|
use std::{alloc::Layout, ffi::{c_char, c_uint, CStr, CString}, path::PathBuf};
|
||||||
|
|
||||||
use dlopen::raw::Library;
|
use dlopen::raw::Library;
|
||||||
|
|
||||||
|
@ -90,6 +90,10 @@ impl Plugin {
|
||||||
let s = unsafe {
|
let s = unsafe {
|
||||||
(self.syms().poll)(buf as *mut i8, cap);
|
(self.syms().poll)(buf as *mut i8, cap);
|
||||||
let len = libc::strlen(buf as *const i8);
|
let len = libc::strlen(buf as *const i8);
|
||||||
|
if len > cap {
|
||||||
|
panic!("String len is bigger than allocatd");
|
||||||
|
}
|
||||||
|
|
||||||
String::from_raw_parts(buf, len, cap)
|
String::from_raw_parts(buf, len, cap)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user