make workspace and upload c-bindings
This commit is contained in:
parent
df52c60f76
commit
fdd538a64f
|
@ -0,0 +1 @@
|
||||||
|
/target
|
|
@ -0,0 +1,36 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "c-bindings"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cty",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cty"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.148"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rs-unsafe"
|
||||||
|
version = "0.1.0"
|
|
@ -0,0 +1,18 @@
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
".",
|
||||||
|
"members/c-bindings"
|
||||||
|
]
|
||||||
|
default-members = [
|
||||||
|
".",
|
||||||
|
"members/c-bindings"
|
||||||
|
]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "rs-unsafe"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
authors = ["Christoph J. Scherr <softwar@cscherr.de>"]
|
||||||
|
publish = false
|
||||||
|
autobins = true
|
||||||
|
default-run = "rs-unsafe"
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "c-bindings"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
links = "test" # this is the important part! cargo will search for some library called `test` (i.e. libtest.a)
|
||||||
|
build = "src/build.rs"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cty = "0.2.2"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = "1.0.83"
|
|
@ -0,0 +1,15 @@
|
||||||
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
project(test VERSION 1.0.1 DESCRIPTION "test lib")
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
add_library(test STATIC test.c)
|
||||||
|
set_target_properties(test PROPERTIES
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
SOVERSION 1
|
||||||
|
PUBLIC_HEADER test.h)
|
||||||
|
# configure_file(test.pc.in test.pc @ONLY)
|
||||||
|
target_include_directories(test PRIVATE .)
|
||||||
|
install(TARGETS test
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/test.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "test.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int ret19() {
|
||||||
|
return 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* structInfo(MyStruct *st) {
|
||||||
|
char* buf = malloc(1024*sizeof(char));
|
||||||
|
sprintf(buf,
|
||||||
|
"Infos about the struct:\n"
|
||||||
|
"\tfoo:\t%d\n"
|
||||||
|
"\tbar:\t%c\n"
|
||||||
|
"\n"
|
||||||
|
"greetings from C"
|
||||||
|
,
|
||||||
|
st->foo,
|
||||||
|
st->bar
|
||||||
|
);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
int ret19();
|
||||||
|
typedef struct MyStruct {
|
||||||
|
int foo;
|
||||||
|
char bar;
|
||||||
|
} MyStruct;
|
||||||
|
char* stuctInfo(MyStruct st);
|
|
@ -0,0 +1,11 @@
|
||||||
|
/// we could simply do this to compile the test lib to a static lib,
|
||||||
|
/// but that solution might not scale as good as calling a professional
|
||||||
|
/// build system
|
||||||
|
#[allow(unused)]
|
||||||
|
fn main() {
|
||||||
|
// Tell Cargo that if the given file changes, to rerun this build script.
|
||||||
|
println!("cargo:rerun-if-changed=src/hello.c");
|
||||||
|
cc::Build::new()
|
||||||
|
.file("lib/test.c")
|
||||||
|
.compile("test");
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
use cty;
|
||||||
|
|
||||||
|
// we first need to declare bindings for our C code.
|
||||||
|
// This can be automated too, but I did it myself here.
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct MyStruct {
|
||||||
|
pub foo: cty::c_int,
|
||||||
|
pub bar: cty::c_char,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The functions too of course
|
||||||
|
extern "C" {
|
||||||
|
pub fn ret19() -> isize;
|
||||||
|
pub fn structInfo(st: &MyStruct) -> *const cty::c_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// calling random C functions is generally treated as unsafe.
|
||||||
|
// Best practice is programming wrapper functions that give it
|
||||||
|
// confirmed safe inputs
|
||||||
|
let qux = unsafe { ret19() };
|
||||||
|
println!("`ret19()` returned {qux}");
|
||||||
|
let st = MyStruct {
|
||||||
|
foo: 17, bar: 0x41
|
||||||
|
};
|
||||||
|
// converting a c "string" to a real rust String is
|
||||||
|
// a bit complicated
|
||||||
|
let info: &str = unsafe {
|
||||||
|
// convert the returned value to a rust internal CStr.
|
||||||
|
std::ffi::CStr::from_ptr(
|
||||||
|
// the function returns a pointer to a array of chars on the heap
|
||||||
|
structInfo(&st)
|
||||||
|
)
|
||||||
|
// now to a string slice (result)
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
println!("{info}");
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
fn main() {
|
||||||
|
println!(
|
||||||
|
"The dark power of unsafe rust awakens!
|
||||||
|
|
||||||
|
This is the default executable! It does not do much, use another executable.
|
||||||
|
|
||||||
|
Select your target like this:
|
||||||
|
`cargo run --bin $TARGET`
|
||||||
|
|
||||||
|
To see a list of all runnable binaries, you can use the following command.
|
||||||
|
`cargo run --bin`
|
||||||
|
");
|
||||||
|
}
|
Loading…
Reference in New Issue