Skip to content

Commit 8d61450

Browse files
committed
first commit
0 parents  commit 8d61450

File tree

8 files changed

+162
-0
lines changed

8 files changed

+162
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
**/*.rs.bk

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "rust-ffi-enum-box"
3+
version = "0.1.0"
4+
authors = ["marmeladema <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
11+
[build-dependencies]
12+
cc = "1.0"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# rust-ffi-enum-box

build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use cc;
2+
3+
fn main() {
4+
cc::Build::new()
5+
.include("include")
6+
.file("src/tests.c")
7+
.warnings(true)
8+
.extra_warnings(true)
9+
.warnings_into_errors(true)
10+
.compile("ctests");
11+
}

include/tests.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef _TESTS_H_
2+
#define _TESTS_H_
3+
4+
#include <stdlib.h>
5+
#include <stdint.h>
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
// https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md
12+
typedef enum {
13+
SCHEME_TYPE_TAG_IP,
14+
SCHEME_TYPE_TAG_BYTES,
15+
SCHEME_TYPE_TAG_INT,
16+
SCHEME_TYPE_TAG_BOOL,
17+
SCHEME_TYPE_TAG_ARRAY,
18+
SCHEME_TYPE_TAG_MAP,
19+
} scheme_type_tag_t;
20+
21+
typedef struct {
22+
scheme_type_tag_t tag;
23+
void *data[1];
24+
} scheme_type_t;
25+
26+
static const scheme_type_t SCHEME_TYPE_IP = {.tag = SCHEME_TYPE_TAG_IP, .data = {NULL}};
27+
static const scheme_type_t SCHEME_TYPE_BYTES = {.tag = SCHEME_TYPE_TAG_BYTES, .data = {NULL}};
28+
static const scheme_type_t SCHEME_TYPE_INT = {.tag = SCHEME_TYPE_TAG_INT, .data = {NULL}};
29+
static const scheme_type_t SCHEME_TYPE_BOOL = {.tag = SCHEME_TYPE_TAG_BOOL, .data = {NULL}};
30+
31+
typedef struct scheme scheme_t;
32+
33+
scheme_t *scheme_new();
34+
void scheme_free(scheme_t *);
35+
36+
void scheme_set_type(scheme_t *scheme, scheme_type_t ty);
37+
38+
void scheme_print(scheme_t *scheme);
39+
40+
#ifdef __cplusplus
41+
}
42+
#endif
43+
44+
#endif // _TESTS_H_

src/main.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#[derive(Debug)]
2+
#[repr(C)]
3+
pub enum SchemeType {
4+
Ip,
5+
Bytes,
6+
Int,
7+
Bool,
8+
Array(Box<SchemeType>),
9+
Map(Box<SchemeType>),
10+
}
11+
12+
#[derive(Debug)]
13+
pub struct Scheme {
14+
ty: Option<SchemeType>,
15+
}
16+
17+
#[no_mangle]
18+
pub extern "C" fn scheme_new() -> *mut Scheme {
19+
Box::into_raw(Box::new(Scheme { ty: None }))
20+
}
21+
22+
#[no_mangle]
23+
pub extern "C" fn scheme_free(scheme: *mut Scheme) {
24+
unsafe {
25+
Box::from_raw(scheme);
26+
}
27+
}
28+
29+
#[no_mangle]
30+
pub extern "C" fn scheme_set_type(scheme: *mut Scheme, ty: SchemeType) {
31+
unsafe {
32+
(*scheme).ty = Some(ty);
33+
}
34+
}
35+
36+
#[no_mangle]
37+
pub extern "C" fn scheme_print(scheme: *mut Scheme) {
38+
unsafe {
39+
println!("{:?}", (*scheme));
40+
}
41+
}
42+
43+
extern "C" {
44+
fn scheme_ctest_01();
45+
fn scheme_ctest_02();
46+
}
47+
48+
fn main() {
49+
println!("Hello, world!");
50+
println!(
51+
"sizeof(SchemeType) = {:?}",
52+
std::mem::size_of::<SchemeType>()
53+
);
54+
unsafe { scheme_ctest_01() };
55+
unsafe { scheme_ctest_02() };
56+
}

src/tests.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "tests.h"
2+
3+
void scheme_ctest_01() {
4+
scheme_t *scheme = scheme_new();
5+
scheme_print(scheme);
6+
scheme_set_type(scheme, SCHEME_TYPE_INT);
7+
scheme_print(scheme);
8+
scheme_free(scheme);
9+
}
10+
11+
void scheme_ctest_02() {
12+
scheme_t *scheme = scheme_new();
13+
scheme_print(scheme);
14+
scheme_type_t *ty = (scheme_type_t *)malloc(sizeof(scheme_type_t));
15+
*ty = SCHEME_TYPE_INT;
16+
scheme_set_type(scheme, *ty);
17+
free(ty);
18+
scheme_print(scheme);
19+
scheme_free(scheme);
20+
}

0 commit comments

Comments
 (0)