I have not benchmark it.
I have try to design rust wrapper with the minimal footprint as possible. My guess is (if LTO is enabled) overhead will be pretty low.
For example, if we look at quickfix::Message
:
- it is a wrapper of
quickfix_ffi::FixMessage_t
- which is a wrapper of
std::ptr::NonNull<ffi::c_void>
- which will be used in
quickfix-bind
library to directly call quickfix c++ functions.
Moreover you can check quickfix::Message
size is the size of a pointer.
You can take for example what I have done to generate coinbase FIX 4.2 package:
- Crate a new sub-package in your workspace (ex:
my-fix51
) - Add the FIX XML spec file in your
src
folder - Add
quickfix
to your dependency - Add
quickfix-msg-gen
to your build dependency - Add
src/lib.rs
with following content:
include!(concat!(env!("OUT_DIR"), "/code.rs"));
- Add
build.rs
with following content:
use std::{env, io};
use quickfix_msg_gen::*;
const SPEC_FILENAME: &str = "src/my-spec-fix51.xml";
const BEGIN_STRING: &str = "FIX.5.1";
fn main() -> io::Result<()> {
let out_dir = env::var("OUT_DIR").expect("Missing OUT_DIR");
generate(SPEC_FILENAME, format!("{out_dir}/code.rs"), BEGIN_STRING)?;
Ok(())
}
Generating struct
/ enum
from multiple XML spec file is hard.
How do you track the source XML file ?
How to deal with duplicated definition and message order ?
To resolve this issue it is simple: you have to work with only one XML spec file.
I have few utilities in quickfix-spec-parser
to help you merging multiple XML spec files.
It will not solve every problem, so you might still have to double check output XML on your own.
For example, here is the command I used to generated FIX 5.0 spec from its source files:
cargo r --example spec-merger -- ./quickfix-msg50/src/FIX{T11,50}.xml > ./quickfix-msg50/src/spec.xml
PR about improving this utilities are always welcomed 😁.
I do not own the "coinbase" name and do not own their XML spec file.
I am also not working for / with them.
So, I legally cannot publish theses examples.
They are just there to show you how to make your own package from an XML spec file.
Build C binding library:
mkdir build
cd build
CFLAGS="-I$HOME/.local/include" CXXFLAGS="-I$HOME/.local/include" LDFLAGS="-L$HOME/.local/lib" cmake \
-DCMAKE_BUILD_TYPE=Release \
-DQUICKFIX_BIND_EXAMPLES=ON \
../quickfix-ffi
make
Run C binding example:
LD_LIBRARY_PATH="$HOME/.local/lib" ./examples/demo_basic_binding ../examples/configs/settings.ini
Rust FFI example:
cargo r --example demo_basic_ffi -- examples/configs/settings.ini
Run rust full binding example:
cargo r --example fix_getting_started -- examples/configs/server.ini
cargo r --example fix_repl -- acceptor examples/configs/server.ini
cargo r --example fix_repl -- initiator examples/configs/client.ini