Skip to content

Commit 79ce454

Browse files
committed
Merge pull request #19968 from steveklabnik/gh10489
Add an example to the FFI guide Reviewed-by: alexcrichton
2 parents 78d6d53 + a5e3849 commit 79ce454

File tree

1 file changed

+46
-28
lines changed

1 file changed

+46
-28
lines changed

src/doc/trpl/ffi.md

+46-28
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ snappy includes a C interface (documented in
1111
The following is a minimal example of calling a foreign function which will
1212
compile if snappy is installed:
1313

14-
~~~~no_run
14+
```no_run
1515
extern crate libc;
1616
use libc::size_t;
1717
@@ -24,7 +24,7 @@ fn main() {
2424
let x = unsafe { snappy_max_compressed_length(100) };
2525
println!("max compressed length of a 100 byte buffer: {}", x);
2626
}
27-
~~~~
27+
```
2828

2929
The `extern` block is a list of function signatures in a foreign library, in
3030
this case with the platform's C ABI. The `#[link(...)]` attribute is used to
@@ -44,7 +44,7 @@ keeping the binding correct at runtime.
4444

4545
The `extern` block can be extended to cover the entire snappy API:
4646

47-
~~~~no_run
47+
```no_run
4848
extern crate libc;
4949
use libc::{c_int, size_t};
5050
@@ -66,7 +66,7 @@ extern {
6666
compressed_length: size_t) -> c_int;
6767
}
6868
# fn main() {}
69-
~~~~
69+
```
7070

7171
# Creating a safe interface
7272

@@ -79,7 +79,7 @@ vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous
7979
length is number of elements currently contained, and the capacity is the total size in elements of
8080
the allocated memory. The length is less than or equal to the capacity.
8181

82-
~~~~
82+
```
8383
# extern crate libc;
8484
# use libc::{c_int, size_t};
8585
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@@ -89,7 +89,7 @@ pub fn validate_compressed_buffer(src: &[u8]) -> bool {
8989
snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
9090
}
9191
}
92-
~~~~
92+
```
9393

9494
The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, but it makes the
9595
guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
@@ -103,7 +103,7 @@ required capacity to hold the compressed output. The vector can then be passed t
103103
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
104104
the true length after compression for setting the length.
105105

106-
~~~~
106+
```
107107
# extern crate libc;
108108
# use libc::{size_t, c_int};
109109
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@@ -124,12 +124,12 @@ pub fn compress(src: &[u8]) -> Vec<u8> {
124124
dst
125125
}
126126
}
127-
~~~~
127+
```
128128

129129
Decompression is similar, because snappy stores the uncompressed size as part of the compression
130130
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
131131

132-
~~~~
132+
```
133133
# extern crate libc;
134134
# use libc::{size_t, c_int};
135135
# unsafe fn snappy_uncompress(compressed: *const u8,
@@ -159,7 +159,7 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> {
159159
}
160160
}
161161
}
162-
~~~~
162+
```
163163

164164
For reference, the examples used here are also available as an [library on
165165
GitHub](https://github.com/thestinger/rust-snappy).
@@ -208,7 +208,7 @@ A basic example is:
208208

209209
Rust code:
210210

211-
~~~~no_run
211+
```no_run
212212
extern fn callback(a: i32) {
213213
println!("I'm called from C with value {0}", a);
214214
}
@@ -225,11 +225,11 @@ fn main() {
225225
trigger_callback(); // Triggers the callback
226226
}
227227
}
228-
~~~~
228+
```
229229

230230
C code:
231231

232-
~~~~c
232+
```c
233233
typedef void (*rust_callback)(int32_t);
234234
rust_callback cb;
235235

@@ -241,7 +241,7 @@ int32_t register_callback(rust_callback callback) {
241241
void trigger_callback() {
242242
cb(7); // Will call callback(7) in Rust
243243
}
244-
~~~~
244+
```
245245
246246
In this example Rust's `main()` will call `trigger_callback()` in C,
247247
which would, in turn, call back to `callback()` in Rust.
@@ -261,7 +261,7 @@ referenced Rust object.
261261
262262
Rust code:
263263
264-
~~~~no_run
264+
```no_run
265265
#[repr(C)]
266266
struct RustObject {
267267
a: i32,
@@ -292,11 +292,11 @@ fn main() {
292292
trigger_callback();
293293
}
294294
}
295-
~~~~
295+
```
296296

297297
C code:
298298

299-
~~~~c
299+
```c
300300
typedef void (*rust_callback)(void*, int32_t);
301301
void* cb_target;
302302
rust_callback cb;
@@ -310,7 +310,7 @@ int32_t register_callback(void* callback_target, rust_callback callback) {
310310
void trigger_callback() {
311311
cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust
312312
}
313-
~~~~
313+
```
314314
315315
## Asynchronous callbacks
316316
@@ -389,13 +389,13 @@ the `link_args` attribute. This attribute is applied to `extern` blocks and
389389
specifies raw flags which need to get passed to the linker when producing an
390390
artifact. An example usage would be:
391391
392-
~~~ no_run
392+
``` no_run
393393
#![feature(link_args)]
394394
395395
#[link_args = "-foo -bar -baz"]
396396
extern {}
397397
# fn main() {}
398-
~~~
398+
```
399399

400400
Note that this feature is currently hidden behind the `feature(link_args)` gate
401401
because this is not a sanctioned way of performing linking. Right now rustc
@@ -416,9 +416,9 @@ the compiler that the unsafety does not leak out of the block.
416416
Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
417417
this:
418418

419-
~~~~
419+
```
420420
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
421-
~~~~
421+
```
422422

423423
This function can only be called from an `unsafe` block or another `unsafe` function.
424424

@@ -428,7 +428,7 @@ Foreign APIs often export a global variable which could do something like track
428428
global state. In order to access these variables, you declare them in `extern`
429429
blocks with the `static` keyword:
430430

431-
~~~no_run
431+
```no_run
432432
extern crate libc;
433433
434434
#[link(name = "readline")]
@@ -440,13 +440,13 @@ fn main() {
440440
println!("You have readline version {} installed.",
441441
rl_readline_version as int);
442442
}
443-
~~~
443+
```
444444

445445
Alternatively, you may need to alter global state provided by a foreign
446446
interface. To do this, statics can be declared with `mut` so rust can mutate
447447
them.
448448

449-
~~~no_run
449+
```no_run
450450
extern crate libc;
451451
452452
use std::ffi::CString;
@@ -463,15 +463,15 @@ fn main() {
463463
// get a line, process it
464464
unsafe { rl_prompt = ptr::null(); }
465465
}
466-
~~~
466+
```
467467

468468
# Foreign calling conventions
469469

470470
Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
471471
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
472472
conventions. Rust provides a way to tell the compiler which convention to use:
473473

474-
~~~~
474+
```
475475
extern crate libc;
476476
477477
#[cfg(all(target_os = "win32", target_arch = "x86"))]
@@ -481,7 +481,7 @@ extern "stdcall" {
481481
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
482482
}
483483
# fn main() { }
484-
~~~~
484+
```
485485

486486
This applies to the entire `extern` block. The list of supported ABI constraints
487487
are:
@@ -541,3 +541,21 @@ with one of the non-nullable types, it is represented as a single pointer,
541541
and the non-data variant is represented as the null pointer. So
542542
`Option<extern "C" fn(c_int) -> c_int>` is how one represents a nullable
543543
function pointer using the C ABI.
544+
545+
# Calling Rust code from C
546+
547+
You may wish to compile Rust code in a way so that it can be called from C. This is
548+
fairly easy, but requires a few things:
549+
550+
```
551+
#[no_mangle]
552+
pub extern fn hello_rust() -> *const u8 {
553+
"Hello, world!\0".as_ptr()
554+
}
555+
```
556+
557+
The `extern` makes this function adhere to the C calling convention, as
558+
discussed above in "[Foreign Calling
559+
Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle`
560+
attribute turns off Rust's name mangling, so that it is easier to link to.
561+

0 commit comments

Comments
 (0)