@@ -240,6 +240,74 @@ the release of these resources (especially in the case of panic).
240
240
241
241
For more about destructors, see the [ Drop trait] ( ../std/ops/trait.Drop.html ) .
242
242
243
+ ## Calling Rust code from C
244
+
245
+ You may wish to compile Rust code in a way so that it can be called from C.
246
+ This is fairly easy, but requires a few things.
247
+
248
+ ### Rust side
249
+
250
+ First, we assume you have a lib crate named as ` rust_from_c ` .
251
+ ` lib.rs ` should have Rust code as following:
252
+
253
+ ``` rust
254
+ #[no_mangle]
255
+ pub extern " C" fn hello_from_rust () {
256
+ println! (" Hello from Rust!" );
257
+ }
258
+ # fn main () {}
259
+ ```
260
+
261
+ The ` extern "C" ` makes this function adhere to the C calling convention, as discussed above in "[ Foreign Calling Conventions] ".
262
+ The ` no_mangle ` attribute turns off Rust's name mangling, so that it has a well defined symbol to link to.
263
+
264
+ Then, to compile Rust code as a shared library that can be called from C, add the following to your ` Cargo.toml ` :
265
+
266
+ ``` toml
267
+ [lib ]
268
+ crate-type = [" cdylib" ]
269
+ ```
270
+
271
+ (NOTE: We could also use the ` staticlib ` crate type but it needs to tweak some linking flags.)
272
+
273
+ Run ` cargo build ` and you're ready to go on the Rust side.
274
+
275
+ [ Foreign Calling Conventions ] : ffi.md#foreign-calling-conventions
276
+
277
+ ### C side
278
+
279
+ We'll create a C file to call the ` hello_from_rust ` function and compile it by ` gcc ` .
280
+
281
+ C file should look like:
282
+
283
+ ``` c
284
+ int main () {
285
+ hello_from_rust ();
286
+ return 0;
287
+ }
288
+ ```
289
+
290
+ We name the file as ` call_rust.c ` and place it on the crate root.
291
+ Run the following to compile:
292
+
293
+ ``` sh
294
+ gcc call_rust.c -o call_rust -lrust_from_c -L./target/debug
295
+ ```
296
+
297
+ ` -l ` and ` -L ` tell gcc to find our Rust library.
298
+
299
+ Finally, we can call Rust code from C with ` LD_LIBRARY_PATH ` specified:
300
+
301
+ ``` sh
302
+ $ LD_LIBRARY_PATH=./target/debug ./call_rust
303
+ Hello from Rust!
304
+ ```
305
+
306
+ That's it!
307
+ For more realistic example, check the [ ` cbindgen ` ] .
308
+
309
+ [ `cbindgen` ] : https://github.com/eqrion/cbindgen
310
+
243
311
## Callbacks from C code to Rust functions
244
312
245
313
Some external libraries require the usage of callbacks to report back their
@@ -648,24 +716,6 @@ void register(void (*f)(int (*)(int), int)) {
648
716
649
717
No `transmute` required!
650
718
651
- ## Calling Rust code from C
652
-
653
- You may wish to compile Rust code in a way so that it can be called from C. This is
654
- fairly easy, but requires a few things:
655
-
656
- ```rust
657
- #[no_mangle]
658
- pub extern "C" fn hello_rust() -> *const u8 {
659
- "Hello, world!\0".as_ptr()
660
- }
661
- # fn main() {}
662
- ```
663
-
664
- The ` extern "C" ` makes this function adhere to the C calling convention, as
665
- discussed above in "[ Foreign Calling
666
- Conventions] ( ffi.html#foreign-calling-conventions ) ". The ` no_mangle `
667
- attribute turns off Rust's name mangling, so that it is easier to link to.
668
-
669
719
## FFI and panics
670
720
671
721
It’s important to be mindful of `panic!`s when working with FFI. A `panic!`
0 commit comments