struct Foo { ... }
fn create_foo() -> Foo {
let foo = Foo { ... };
foo
}
// A module containing all the types and APIs in the external library. | |
mod sys { | |
use std::cmp; | |
use std::ffi::CString; | |
use std::os::raw::{c_char, c_void}; | |
pub type XString = *mut c_void; | |
extern "C" { | |
fn calloc(items: usize, size: usize) -> *mut c_void; |
all: | |
# Sample in C(static library): | |
# gcc -c string_ref.c -o string_ref.o | |
# ar rcs libstringref.a string_ref.o | |
# gcc -c device.c -o device.o | |
# ar rcs libdevice.a device.o | |
# gcc sample.c -L. -ldevice -lstringref -o sample-c | |
# ./sample-c | |
# Sample in C: |
all: | |
# Build a static library from the Rust file | |
rustc --crate-type=staticlib ext.rs | |
# Compile the C file with the static library | |
# gcc -o sample-c sample.c libext.a | |
gcc -o sample-c sample.c -L. -lext | |
./sample-c | |
# g++ -o sample-cpp sample.cpp libext.a | |
g++ -o sample-cpp sample.cpp -L. -lext | |
./sample-cpp |
The key point for this gist repo is to indicate:
Don't misuse the pointers of the instances allocated in functions stack since they will be gone after finishing the function calling.
The sample code here is to demonstrate the problem I have when I am developing a [Rust audio library][draft]. To play sounds, it needs to register callbacks to the underlying OS through audio APIs and then the callbacks will be fired periodically. The callback usually will come with at least 2 parameters:
- a buffer that will be filled with audio data
- a pointer indicating what variable calls the callback.
To create Rust APIs that can play audio, I create a struct for audio stream named Stream
and store all the stream related settings like sampling rate or channels in that struct. There is a struct method named new
that will create a Stream
instance that will be returnd. Before the instance is returned, I use the pointer of
#[path = ""] | |
mod utils { | |
#[path = "audio_object.rs"] | |
mod audio_object; | |
use self::audio_object::{get_property_data, sys::*}; | |
use std::fmt; // For fmt::{Display, Formatter, Formatter} | |
#[derive(PartialEq)] | |
pub enum Scope { |
all: | |
# Sample in C: | |
# gcc -shared -fPIC device.c -o libdevice.so | |
# gcc sample.c libdevice.so -o sample-c | |
# ./sample-c | |
# Sample in C++: | |
g++ -std=c++11 -shared -fPIC device.cpp -o libdevice.so | |
g++ -std=c++11 sample.cpp libdevice.so -o sample-cpp | |
./sample-cpp |
#include <cassert> | |
typedef int NewType; | |
struct A { | |
NewType a; | |
}; | |
struct B { | |
NewType b; |
all: | |
gcc -shared -fPIC ext.c -o libext.so | |
rustc problem.rs -L. | |
LD_LIBRARY_PATH=. ./problem | |
rustc solution.rs -L. | |
LD_LIBRARY_PATH=. ./solution | |
clean: | |
rm problem | |
rm solution |
// Converting the error types of inner modules to the error types of outer modules. | |
mod server { | |
use std::fmt; // For fmt::Debug trait. | |
pub enum Error { | |
File(file::Error), | |
Network(network::Error), | |
Others, | |
} |