Skip to content

Commit

Permalink
Merge pull request #5 from not-matthias/ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
not-matthias authored Mar 16, 2023
2 parents 7442786 + 2b22be4 commit 02ccb88
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ members = [
"graphic-offsets",
"inject-helper",
"obs-client",
"obs-client-ffi",
]
13 changes: 13 additions & 0 deletions obs-client-ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "obs-client-ffi"
version = "0.1.0"
edition = "2021"

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

[lib]
name = "obs_client_ffi"
crate-type = ["lib", "cdylib", "staticlib"]

[dependencies]
obs-client = { path = "../obs-client" }
15 changes: 15 additions & 0 deletions obs-client-ffi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# obs-client-ffi

## Requirements

```
cargo +nightly install cbindgen
```

## Headers

Generate with:
```
cbindgen --config cbindgen.toml --crate obs-client-ffi --output obs-client.h -l C
cbindgen --config cbindgen.toml --crate obs-client-ffi --output obs-client.hpp -l C++
```
14 changes: 14 additions & 0 deletions obs-client-ffi/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language = "C++"

include_guard = "OBS_CLIENT_H"
tab_width = 4
style = "both"
cpp_compat = true

after_includes = "typedef void *Capture;"

[fn]
sort_by = "None"

[enum]
prefix_with_name = true
32 changes: 32 additions & 0 deletions obs-client-ffi/obs-client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef OBS_CLIENT_H
#define OBS_CLIENT_H

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *Capture;

typedef struct Frame {
uintptr_t width;
uintptr_t height;
uint8_t *data;
} Frame;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

Capture *create_capture(const char *name_str);

void free_capture(Capture *capture);

bool try_launch_capture(Capture *capture);

struct Frame *capture_frame(Capture *capture);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif /* OBS_CLIENT_H */
29 changes: 29 additions & 0 deletions obs-client-ffi/obs-client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef OBS_CLIENT_H
#define OBS_CLIENT_H

#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
typedef void *Capture;

struct Frame {
uintptr_t width;
uintptr_t height;
uint8_t *data;
};

extern "C" {

Capture *create_capture(const char *name_str);

void free_capture(Capture *capture);

bool try_launch_capture(Capture *capture);

Frame *capture_frame(Capture *capture);

} // extern "C"

#endif // OBS_CLIENT_H
63 changes: 63 additions & 0 deletions obs-client-ffi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use obs_client::Capture;
use std::ffi::{c_char, CStr};

#[no_mangle]
pub extern "C" fn create_capture(name_str: *const c_char) -> *mut Capture {
let name = unsafe { CStr::from_ptr(name_str).to_string_lossy().into_owned() };

let capture = Capture::new(name.as_str());
Box::into_raw(Box::new(capture))
}

#[no_mangle]
pub extern "C" fn free_capture(capture: *mut Capture) {
if capture.is_null() {
return;
}
let capture = unsafe { Box::from_raw(capture) };
core::mem::drop(capture);
}

#[no_mangle]
pub extern "C" fn try_launch_capture(capture: *mut Capture) -> bool {
if capture.is_null() {
return false;
}

if let Err(e) = unsafe { (*capture).try_launch() } {
eprintln!("Failed to launch capture: {:?}", e);
false
} else {
true
}
}

#[repr(C)]
pub struct Frame {
width: usize,
height: usize,
data: *mut u8,
}

#[no_mangle]
pub extern "C" fn capture_frame(capture: *mut Capture) -> *mut Frame {
if capture.is_null() {
return std::ptr::null_mut();
}

let frame = unsafe { (*capture).capture_frame() };
let (data, (width, height)) = match frame {
Ok(frame) => frame,
Err(e) => {
eprintln!("Failed to capture frame: {:?}", e);
return std::ptr::null_mut();
}
};

let frame = Frame {
width,
height,
data: data.as_mut_ptr(),
};
Box::into_raw(Box::new(frame))
}
3 changes: 0 additions & 3 deletions obs-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#![feature(bool_to_option)]
#![feature(cstring_from_vec_with_nul)]

use crate::{
error::ObsError,
hook_info::{
Expand Down

0 comments on commit 02ccb88

Please sign in to comment.