File tree 7 files changed +104
-0
lines changed
7 files changed +104
-0
lines changed Original file line number Diff line number Diff line change @@ -49,3 +49,4 @@ in a controlled repository now.
49
49
* ` macro-nargs.rs ` : example of recursive macro
50
50
* ` macro-tt.rs ` : macro token tree example
51
51
* ` nullptr.rs ` : null pointer example
52
+ * ` c++-ffi/ ` : example of FFI between C, C++ and Rust
Original file line number Diff line number Diff line change
1
+ CC = clang
2
+ CXX = clang++
3
+ RUSTC = rustc -C panic="abort"
4
+
5
+ OBJS = add1-c.o add1-rs.a demo.o
6
+
7
+ TARGETS = demo-c demo-rs
8
+
9
+ all : $(TARGETS )
10
+
11
+ demo-c : demo.o add1-c.o
12
+ $(CXX ) -o demo-c demo.o add1-c.o
13
+
14
+ demo-rs : demo.o add1-rs.a
15
+ $(CXX ) -o demo-rs demo.o add1-rs.a -lpthread -ldl
16
+
17
+ add1-c.o :
18
+ $(CC ) -c -o add1-c.o add1.c
19
+
20
+ add1-rs.a : add1.rs
21
+ $(RUSTC ) -o add1-rs.a add1.rs
22
+
23
+ clean :
24
+ -rm -f $(TARGETS ) $(OBJS )
Original file line number Diff line number Diff line change
1
+ # c++-ffi: Providing a C function to C++ code from Rust or C.
2
+
3
+ This directory contains
4
+
5
+ * A C++ driver ` demo.cc `
6
+
7
+ * A function called by the driver and written in C in ` add1.c `
8
+
9
+ * A function called by the driver and written in Rust in
10
+ ` add1.rs `
11
+
12
+ * A ` Makefile ` that makes the whole thing compile
13
+
14
+ This has only been tested on Debian Linux with ` clang ` /
15
+ ` clang++ ` : other platforms and compilers might work. Who
16
+ knows?
17
+
18
+ The ` demo-rs ` executable is quite large: 4MB before stripping
19
+ debug symbols, 1MB after. The executable brings in big
20
+ pieces of ` std ` for various reasons. The good news is that
21
+ this scales reasonably — adding a bunch of extra Rust isn't
22
+ going to change it substantially.
23
+
24
+ The build is controlled by ` make ` . One could add a fancy
25
+ ` build.rs ` and build it all with Cargo; doesn't seem worth
26
+ it here.
Original file line number Diff line number Diff line change
1
+ #include <stdio.h>
2
+
3
+ #include <inttypes.h>
4
+ int64_t add1 (int64_t * x , char * msg ) {
5
+ * x += 1 ;
6
+ printf ("%s %ld\n" , msg , * x );
7
+ return * x ;
8
+ }
Original file line number Diff line number Diff line change
1
+ #include < iostream>
2
+
3
+ using namespace std ;
4
+
5
+ extern " C" {
6
+ #include < inttypes.h>
7
+ int64_t add1 (int64_t *x, char * msg) {
8
+ *x += 1 ;
9
+ cout << msg << " " << *x << endl;
10
+ return *x;
11
+ }
12
+ }
Original file line number Diff line number Diff line change
1
+ #![ crate_type = "staticlib" ]
2
+
3
+ use std:: ffi:: CStr ;
4
+ use std:: os:: raw:: c_char;
5
+
6
+ #[ no_mangle]
7
+ /// Add 1 to the number referenced by `x`, print the result of the add along with `msg`, return
8
+ /// the result.
9
+ ///
10
+ /// # Safety
11
+ ///
12
+ /// `msg` must point to a valid C string, and `x` must point to a valid C `uint64_t`.
13
+ pub unsafe extern "system" fn add1 ( x : & mut i64 , msg : * const c_char ) -> i64 {
14
+ let msg = CStr :: from_ptr ( msg) ;
15
+ * x += 1 ;
16
+ println ! ( "{} {}" , msg. to_string_lossy( ) , * x) ;
17
+ * x
18
+ }
Original file line number Diff line number Diff line change
1
+ #include < iostream>
2
+
3
+ extern " C" {
4
+ #include < inttypes.h>
5
+ extern int64_t add1 (int64_t *, char *);
6
+ }
7
+
8
+ using namespace std ;
9
+
10
+ int main () {
11
+ int64_t x = 3 ;
12
+ int64_t y = add1 (&x, (char *) " working with" );
13
+ cout << " got " << x << " " << y << endl;
14
+ return 0 ;
15
+ }
You can’t perform that action at this time.
0 commit comments