Expand description
Defines the types and helpers for binary/library communication.
The general idea is that the user will run a driver program which calls
game_init
to get a handle, and then gets lines from the user and passes
them to game_process_line
, and prints the output. At some point the
driving program might try to exit cleanly, and if so it’ll call game_drop
.
Of course, the driving program might suddenly die at any moment without
game_drop
ever being called, so I wouldn’t rely on that happening.
Note that all of the interchange types are fully compatible with the C ABI, so you don’t have to use Rust if you don’t want to. As long as you follow the types you can write your DLL and/or driving program in any language you like.
To be loaded properly, your DLL should have one function of each function type given here, named in snake_case without the “Fn” part at the end:
GameInitFn
:game_init
GameProcessLineFn
:game_process_line
GameDropFn
:game_drop
§Building a game DLL with cargo
First, be sure to mark your functions with #[no_mangle]
and pub
. You
must also have “cdylib” as one of your crate-type
values for your crate’s
library portion. If you want cargo test
to work properly, you’ll need
“rlib” as well. It’ll look something like this:
[lib]
name = "vibha"
path = "src/lib.rs"
crate-type = ["rlib", "cdylib"]
You can easily ensure that your functions have the correct type at compile
time with a simple set of const
declarations.
A “complete” example might look something like this.
extern crate vibha;
use vibha::*;
use std::io::Write;
use std::os::raw::c_void;
struct GameState {
world_seed: u64,
call_count: u64,
}
#[no_mangle]
pub unsafe extern "C" fn game_init(world_seed: u64) -> *mut c_void {
Box::into_raw(Box::new(GameState {
world_seed,
call_count: 0
})) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn game_process_line(handle: *mut c_void,
line: *const u8, line_len: usize, mut buf: *mut u8, buf_len: usize) -> usize {
if handle.is_null() || line.is_null() || buf.is_null() {
return 0;
}
let user_line = ffi_recover_str(&line, line_len);
let mut out_buffer = ffi_recover_out_buffer(&mut buf, buf_len);
let game_state: &mut GameState =
(handle as *mut GameState).as_mut().expect("game session was null!");
// do something silly just so we can see an effect
game_state.call_count += 1;
if user_line.len() > 0 {
write!(out_buffer, "{}: {}", game_state.call_count, user_line).ok();
} else {
write!(out_buffer, "{}: {}", game_state.call_count, game_state.world_seed).ok();
}
out_buffer.position() as usize
}
#[no_mangle]
pub unsafe extern "C" fn game_drop(handle: *mut c_void) {
Box::from_raw(handle as *mut GameState);
}
#[allow(dead_code)]
const GAME_INIT_CONST: GameInitFn = game_init;
#[allow(dead_code)]
const GAME_PROCESS_LINE_CONST: GameProcessLineFn = game_process_line;
#[allow(dead_code)]
const GAME_DROP_CONST: GameDropFn = game_drop;
Structs§
- Allows you to specify a protocol version.
Enums§
- Wraps a string slice with a “mode” tag.
Constants§
- Signals that the driver supports ANSI color outputs.
- Makes the background black until the end of this output
- Makes the background blue until the end of this output
- Makes the background cyan until the end of this output
- Makes the background green until the end of this output
- Makes the background magenta until the end of this output
- Makes the background red until the end of this output
- Makes the background white until the end of this output
- Makes the background yellow until the end of this output
- Makes the foreground black until the end of this output
- Makes the foreground blue until the end of this output
- Makes the foreground cyan until the end of this output
- Makes the foreground green until the end of this output
- Makes the foreground magenta until the end of this output
- Makes the foreground red until the end of this output
- Makes the foreground white until the end of this output
- Makes the foreground yellow until the end of this output
- Requests the game to display its introduction.
- The prefix for the formatted vibha version header.
Functions§
- Converts the pointer and len for the output buffer into a rusty form.
- Converts the const pointer and len for the user’s input line into a rusty form.
- Filters the results of
mode_split_str
into just the textual part. - Breaks up a
&str
in the special way demanded by theGameProcessLineFn
docs.
Type Aliases§
- Frees up the game session data.
- Initializes a game session.
- Processes a single line of user input.